There are two common scenarios for a front-end file download
- When the file is uploaded to the resource server, the backend saves only the file address, and the front-end directly downloads the file address returned by the backend.
- The file is stored on the back-end server (usually generated dynamically on a temporary basis based on front-end parameters and deleted when used), and the backend reads the file and returns a binary stream of the file to the front-end.
The following uses downloading excel files as an example to simulate the two situations. (Vscode, node8+, vuE-cli3.5 +).
Download directly through the file address
Create a service directory under the empty directory test to simulate the back end, and create an index. HTML file to simulate the front end.
Create an Excel file named test.xlsx in the service directory for download.
Install serve to start the static resource server
npm install -g serve
Copy the code
Go to the service directory and start the service
cd service
serve -s
Copy the code
At this point the test file address is: http://localhost:5000/test.xlsx
Put an A tag in the page and put the path of the file in href and the Download attribute.
At < a href = "http://localhost:5000/test.xlsx" > click download < / a >Copy the code
Open index.html in your browser and click Download.
This download is equivalent to a GET request. The browser accesses the static resource directly, and the Download attribute tells the browser that the A TAB is not open for a page preview but for a download.
This has nothing to do with the usual ajax request for the interface in a real project, just the usual request, because the back end returns only the address of the file, which can be downloaded either by binding it to an A tag or through window.open(), rather than demonstrating it separately in the project.
Download binary stream files
This is typically the way real projects use ajax request interfaces, such as POST requests, where the front end passes several parameters and the back end returns a binary stream of files.
Delete index.html, go back to the test directory, and create a vue project using vue-CLI.
cd .. / vue create demoCopy the code
Select the simplest default template, go to your project directory, install Axios, and start.
cd demo
npm i axios --save
npm run serve
Copy the code
Remove superfluous content from SRC/app.vue and add a download button.
<input type="button" value=" button" >Copy the code
Create service.js in the service directory to write a download interface.
For details about cross-domain CORS Settings, see juejin.cn/post/684490…
const http = require("http"); const fs = require("fs"); Const server = http.createserver ((req,res) => {if(req.url === "/download") {res.writehead (200, {" content-type ": "application/vnd.ms-excel", // return to excel file // set access-Control-allow-origin ": "*", "Access-Control-Allow-Headers": Fs.readfile ("test.xlsx", (err, Data) => {// Return binary stream file res.end(data)})}}) // The service starts on port 3000 server.listen(3000) console.log("server run at 3000")Copy the code
Open a new terminal window in the Service directory to start the back-end service.
node service.js
Copy the code
Go back to app.vue and add a click event to the download button.
<input type="button" value=" handleDownload" @click="handleDownload"> handleDownload() {axios({method: 'post', url: "http://localhost:3000/download", data: { test: "test data" } }).then(response => { console.log(response.data) }) },Copy the code
Click download and you can see that the result is garbled.
In fact, the basic principle is the same as the above ordinary download, are through a file address to download, so now the key is now to generate these binary data a file URL.
First set the AXIOS configuration item to return the result in binary format.
axios({ method: 'post', url: "http://localhost:3000/download", data: { test: "test data" }, responseType: "Arraybuffer" // arrayBuffer is the interface in JS that provides the processing of binary})Copy the code
After taking the returned data, generate a file URL from the binary data. CreateObjectURL generates the URL with Blob parameters.
About Blob types: juejin.cn/post/684490…
After the URL is generated, it is simulated a tag to download.
Then (response => {let Blob = new Blob([response.data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }) / / for. XLSX files / / by URL. CreateObjectURL generated file path let URL = window. URL. CreateObjectURL (blob) / / create a tag let ele = Document.createelement ("a") ele.style.display = 'none' // Set href attribute to file path, Download property can set the file name ele.href = URL ele.download = "test file" // add the A tag to the page and simulate clicking Document. QuerySelectorAll (" body ") [0]. The appendChild (ele) ele. Click () / / to remove a tag ele. Remove ()});Copy the code
Go back to the browser and click Download. This time the binary stream file is downloaded successfully.
After the