2

I have below vuex method for download file :

   downloadFile(context, url) {
      return new promise((resolve, reject) => {
        const method = "GET";
        axios
          .request({
            url: url,
            method,
            responseType: "blob"
          })
          .then(response => {
            let fileURL = window.URL.createObjectURL(
              new Blob([response.data]),
              {
                type: response.headers["content-type"]
              }
            );
            let fileLink = document.createElement("a");
            fileLink.href = fileURL;
            let fileName = response.headers["content-disposition"].split(
              "filename="
            )[1];
         
            fileLink.setAttribute("download", fileName);
            document.body.appendChild(fileLink);

            fileLink.click();
            fileLink.remove();
            resolve();
          })
          .catch(() => {
            reject();
          });
      });
    }

I pass the URL link (getting from laravel API)

Blockquote

the problem that the file always downloaded with txt extension

Blockquote

There is any method to get the file extension? enter image description here

Alaa
  • 167
  • 1
  • 3
  • 10
  • Your server didn't send the file extension in the screenshot. So you can either 1) Fix your server response to include the extension, or 2) Deduce the extension from the `Content-Type` – Dan Nov 21 '20 at 10:42
  • Is the extension in the `url` passed to `downloadFile`? If so, you can just take it from there too. – Dan Nov 21 '20 at 11:03
  • No it not contain the extension – Alaa Nov 21 '20 at 11:06

2 Answers2

2

Your server didn't send the file extension in the screenshot. If it's not in downloadFile's url argument and you can't fix your server response to include it, you could deduce it from Content-Type. You could create a hash linking each content type to an extension.

Remove this:

let fileName = response.headers["content-disposition"].split(
   "filename="
)[1];

Replace it with this to capture the extension:

const extensions = {
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',
  'application/fake': 'fake', // Just an example
  // etc. Add another line for every Content-Type
}
const contentType = response.headers["Content-Type"];
const extension = extensions[contentType];
const filename = 'file.' + extension;

This will name every file "file.<extension>"

Dan
  • 59,490
  • 13
  • 101
  • 110
0

If your endpoint does not supply the extension you can add it in the fileName. So it could be:

-  fileLink.setAttribute("download", fileName);
+  const extention = 'pdf'; // example
+  fileLink.setAttribute("download", `${fileName}.${extention}`);
Adam Orłowski
  • 4,268
  • 24
  • 33
  • I have multiple types I need it to be dynamic @Adam Orlov – Alaa Nov 21 '20 at 10:28
  • If backend won't give you the information about the file type, somehow you need to figure out what extention to use on your own. Maybe based on some `header` ?. I have showed you how you can save the file with different extention, which is what you asked for . – Adam Orłowski Nov 21 '20 at 10:32
  • Thank you dear,but i need to know how i can get the file extension – Alaa Nov 21 '20 at 10:33
  • Does `Content-Type` header change when getting different files? Maybe based on this header you can figure it out. – Adam Orłowski Nov 21 '20 at 10:38