In the background management system, we often encounter the need for file export. Below, I will give a brief introduction to several common export methods, so that when you encounter such needs in the future, you can be realistic and adopt relative Reasonable way.
Export target
File address
Files that already exist on the server, such as pictures, materials uploaded by users, etc.http://192.168.1.103:3000/imgs/bg.jpg
Export interface
According to user needs, dynamically generated files, such as export business flow table, data summary table, etc.http://192.168.1.103:3000/api/export
Export method
a.download
html5 new attributes
The file name is specified by the front end, and the front end issues a save instruction
Disadvantages: ie does not support, and when cross-domain, even if cross-domain response headers are set in the background, it cannot be downloaded, that is, it must be consistent with the current domain
<a href="http://192.168.1.103:3000/imgs/xx.jpg" download />
<a href="http://192.168.1.103:3000/imgs/xx.jpg" download="xx.jpg" />
ajax + a.download
The file name is specified by the front desk, and the front desk issues a save instruction
Convert the binary data returned in the background into a blob, then use URL.createObjectURL to create a URL pointing to the blob in the memory, and then use the download attribute of the a tag to export
Disadvantages: ie does not support, blobs have memory limitations
But it avoids the problem that a.download must be consistent with the domain name when used alone
function useLinkDownload(url, fileName) {
const link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
$.get('http://192.168.1.103:3000/api/export', { responseType: 'blob' })
.then(function(res) {
// 创建一个指向内存中blob的URL
const objectURL = URL.createObjectURL(res.data);
useLinkDownload(objectURL, 'xx.xlsx')
URL.revokeObjectURL(objectURL)
})
ajax + msSaveBlob
The file name is specified by the front desk, and the front desk issues a save instruction
ie proprietary api
Disadvantages: Chrome and firefox do not support, blobs have memory limitations
$.get('http://192.168.1.103:3000/api/export', { responseType: 'blob' })
.then(function(res) {
navigator.msSaveBlob(res.data, "xx.xlsx");
})
content-disposition
The file name is specified by the background, and the priority of the file name specified in this way is higher than that of a.download
The front-end can send the request (others are handed over to the back-end). When the back-end responds to the data, set content-disposition
according to the specification. One thing to note is that it cannot be combined with ajax (after using ajax, it will become a binary stream, which requires front-end convection processing)
var url = 'http://192.168.1.103:3000/api/export'
a tag
function useLink(url) {
const link = document.createElement("a");
link.style.display = "none";
link.href = url;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
useLink(url)
location.href
function useLocationDownload(url) {
window.location.href = url;
}
useLocationDownload(url)
window.open
function useWindowOpenDownload(url) {
window.open(url);
}
useWindowOpenDownload(url)
form
function useFormDownload(url) {
const form = document.createElement("form");
form.action = url;
form.method = "get";
form.style.display = "none";
document.body.appendChild(form);
form.submit();
form.remove();
}
useFormDownload(url)
iframe
function useIframeDownload(url) {
const iframe = document.createElement("iframe");
iframe.src = url;
iframe.style.display = "none";
document.body.appendChild(iframe);
document.body.removeChild(iframe);
}
useIframeDownload(url)
some problems
Cross-domain
a.download invalid, even if Access-Control-Allow-Origin is set in the background, it is invalid. The value of download needs to be consistent with the current domain name. Let ngnix forward it.
https://html.spec.whatwg.org/dev/links.html#downloading-resources
Large file
The ajax method requires the use of blobs, and there are restrictions on blobs. For example, the upper limit of chrome is 2GB, so the ajax method needs to be excluded. The optional methods are a.download and Content-Disposition. These two methods are not used. blob, so there is no specific limit.
When using a tag or form, in order to avoid page flickering when exporting, we can use target non-_self value to avoid it, but when target is _self, if the export request fails, the page will be overwritten , In which way can I avoid this problem?
Optional methods are ajax and iframe, both of which can avoid overwriting the current page when it fails, and ajax can also tell the user the reason for the failure
to sum up
By default, when the browser faces files that it cannot open, it will save them locally. However, such as pictures, text files and pdfs, the browser first tries to open them. This is reasonable under normal circumstances, but when we This becomes a problem when the purpose is to save rather than open.
Several export methods and their limitations are listed above. In general, Content-Disposition should be a more general method, which takes into account compatibility and avoids browser memory limitations.
data
https://github.com/eligrey/FileSaver.js/wiki/Saving-a-remote-file#using-http-header
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。