You’re proud of how things are working out with your shiny new Vue SPA. You’ve navigated your way over the authentication hurdle by implementing a token-based solution with Axios. Awesome!
You now realize how useful an Excel download of an existing browser-based report would be. Here comes the curve ball. You have to download a file without using HTML links because we’re not using session IDs in cookies for authentication.
There are a few solutions to this. The path of least resistance is to use the authentication system you’ve already setup in your app. That means using Axios to send a request using the pre-configured authentication header and then tell the browser to download the response.
You likely have something similar to this line of code somewhere in your front-end, sending the token authentication header.
this.axios.defaults.headers['Authorization'] = 'Bearer ' + this.store.state.accessToken;
With that in place, we’ll create a button in the component template to download the file.
<button @click="downloadExport">Excel Export</button>
Once that’s set, we’ll create a method in the component to send the request via Axios and tell the browser to download (not render) the response, the Excel file.
methods: { downloadExport() { this.axios.get('/v1/some-endpoint', { // If you forget this, your download will be corrupt. responseType: 'blob' }).then((response) => { // Let's create a link in the document that we'll // programmatically 'click'. const link = document.createElement('a'); // Tell the browser to associate the response data to // the URL of the link we created above. link.href = window.URL.createObjectURL( new Blob([response.data]) ); // Tell the browser to download, not render, the file. link.setAttribute('download', 'report.xlsx'); // Place the link in the DOM. document.body.appendChild(link); // Make the magic happen! link.click(); }); // Please catch me! } }
Now, of course, you should catch any rejections from the promise but you don’t need me for that.
I hope you found this helpful. Have a suggestion to make this article better? Let me know in a comment below.
Photo by Geetanjal Khanna on Unsplash
I got this error
The ‘Access-Control-Allow-Origin’ header contains multiple values ‘http://localhost:8080, http://localhost:8080‘, but only one is allowed
The server side code that sends the header is providing an improperly formatted value. It can be a single origin or an asterisk (*) meaning ‘any’. See more here.
Thank you very much !
You can specify also the mimetype to help your browser to decide it’s a excel file :
new Blob([response.data], {
type: ‘application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’
})
At the end, it’s better to remove the link :
link.click();
URL.revokeObjectURL(link.href);
Thanks dude, you gave the exact solution to my problem.
Just recently learned the responseType option from Axios, createObjectURL and new Blob functionalities. They sure came in handy.