Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue/HTML/JS how to download a file to browser using the download tag

This question is different from the other answer provided, because my question is focused on VUE and if VUE also has a way to prevent the default method.

This question is more specific to HTML 5 "download" along with VUE binding of the :href and why it doesn't work to prevent the default browser behavior of opening the file in a new tab.

Expected behavior : Download the file to the browser

Actual behavior : Opens the file in a new tab

Exception: Only images, pdf and browser compatible files are opened in a new tab, other files like .exe are downloaded as normal - Why is this, can this behavior be changed in html?

Adding target="_blank" does not solve the problem

<a :href="downloadById(item.url)" download>Download</a> 

When the above link is clicked, the file is opened in a new browser tab, i need to prevent this default behavior and force a download upon click. The HTML 5 tag "download" is suppose to solve this problem doesn't seem to work.

Chrome has recently deprecated the download tag form working with cross domain downloads. Does vue have a modifier to prevent this default? Are there any other ways to download the file either in javascript or in html?

One proposed solution is to read the URL as a arrayBuffer and then create a new blob in the DOM, and then create an anchor element and click it.. But that seems hacky to force a download of a file.

I am sure their must be a cleaner solution to download a file form a URL, its a trivial problem, hoping for a simple solution.

Thanks.

like image 468
Ricky-U Avatar asked Dec 14 '18 01:12

Ricky-U


People also ask

How do I prompt a download in HTML?

HTML: Use the anchor element download attribute to prompt the user to download a resource. The download attribute on an anchor tag pops up a Save dialog to download the resource, instead of navigating to it. e.g. Using an attribute value, such as download="cat-1.

How do I download a PDF from Vue?

To download a PDF file with Vue. js, we can create an object URL from the PDF blob response, assign the URL as the value of the href property of an anchor element. And them we call anchor's click method to download it.


2 Answers

You can fetch the file as a blob and provide it the same way, there will be no request that leads into CORS issues.

Template

<a   :href="item.url"   v-text="item.label"   @click.prevent="downloadItem(item)" /> 

Vue

methods: {   downloadItem ({ url, label }) {     Axios.get(url, { responseType: 'blob' })       .then(response => {         const blob = new Blob([response.data], { type: 'application/pdf' })         const link = document.createElement('a')         link.href = URL.createObjectURL(blob)         link.download = label         link.click()         URL.revokeObjectURL(link.href)       }).catch(console.error)   } } 

Notes: I used Axios for my example but that's not a requirement, the blob's mime type is hardwired for the sake of simplicity.

like image 128
Lars Beck Avatar answered Sep 20 '22 08:09

Lars Beck


If you want the browser to handle the download instead of handling the download in JavaScript you need to use window.open:

window.open("<insert URL here>") 

This gives a better user experience IMO but gets tricky to set up when trying to access authorization-protected content. To do this you need to store the authorization in cookies instead of relying on storing the authorization header in the browser's local storage. This will require configuring your server & client to authenticate this way.

To do this client side make sure axios knows to store credentials:

import axios from 'axios' axios.defaults.withCredentials = true 

To do this server side depends on which server you use.

like image 32
HyperActive Avatar answered Sep 20 '22 08:09

HyperActive