E
E
EranosyanEduard2021-07-05 17:45:19
JavaScript
EranosyanEduard, 2021-07-05 17:45:19

How to ensure the download of the pdf file received in the server response using js?

Hello. I am a beginner frontender and the action takes place within the framework of a Vue project.

It is necessary to implement typical functionality: the user sends a request, in response to which a pdf file arrives (the file starts with the line %PDF-1.5), which should be downloaded to the user's computer?

Googling, I found a typical solution that is suggested to be used in such situations, but I honestly admit that I don’t fully understand how it works, and therefore I don’t know how to fix what I get either an empty file or an error when opening such a file. Can you please tell me how to download the file?

I attach a piece of code that tries to process such a file.

this.getSetOfDocumentsByContract(reqBody)
      .then(({ data }) => {
        const objURL = window.URL.createObjectURL(
          new Blob([...data], { type: "application/pdf" })
        );

        this.$refs.anchor.href = objURL;
        this.$refs.anchor.download = "file.pdf";
        this.$refs.anchor.click();

        setTimeout(() => {
          window.URL.revokeObjectURL(data);
        }, 100);

        this.propagateCustomEvt(evt.name);
      })
      .catch((reason) => (this.submitErrorText = "Непредвиденная ошибка"))
      .finally(() => (this.useAgreeButtonLoading = false));


Thanks for the reply, but for some reason using the Blob constructor doesn't achieve the desired result! But the use of a value - the result of calling the blob () method on an object that represents the response from the server results. If possible, please explain what is the matter here?

<script>
      const btn = document.querySelector(".btn");

      btn.addEventListener("click", () => {
        fetch("someUrl", {
          method: "POST",
          headers: {
            "content-type": "application/json",
            "x-api-token": "someToken",
          },
          body: JSON.stringify({
            contractId: 80,
            document: 49904,
            download: true,
          }),
        }).then((v) => {
          v.blob().then((blob) => {
            // Использую метод slice, чтобы файл имел необходимый тип. 
            url = window.URL.createObjectURL(blob.slice(0, blob.size, "application/pdf"));

            const a = document.querySelector(".anchor");

            a.style.display = "none";
            a.href = url;
            a.download = "testFile.pdf";
            a.click();

            window.URL.revokeObjectURL(url);
          });
        });
      });
</script>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Stalker_RED, 2021-07-05
@EranosyanEduard

0. Take data from somewhere
1. Pass it to URL.createObjectURL in it and all the magic happens - a special object is created that the browser can "download".
2. Then take some link (or create a new one), in its href write this url from the previous paragraph
3. Do the link .click () - and the file save dialog is called.
4. The deed is done, the link can be removed, the memory can be cleared (revokeObjectURL)
Here is an example without external dependencies:

If your file is downloaded, but it is empty, then the error when opening is the reason somewhere in point 0, where you receive or generate pdf. And you don't show this code.
To verify this, change the type to text/plain and pass a string like "hello world" to the blob.
Try to transfer the finished PDF, which is definitely not empty and opens normally.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question