如何巧妙的實現文件下載
如何巧妙的實現文件下載
文件上傳下載在業務開發中非常常見,尤其在企業級應用中;實現圖片、報表類文件的下載居多。最近我有贊商品中心后台商品批量改價功能模塊與堂食點單插件功能模塊中就遇到文件下載的需求。
常見的處理方式
一般在文件下載的方式:
window.open
window.open("htpp://127.0.0.1/test.rar");
使用 window.open 是可以實現文件的下載,正常的 zip 、 rar 、 arj 等文件是可以使用 window.open 打開的;window.open 能夠打開的原理是讓我門用瀏覽器打開一個文件時,如果瀏覽器無法解析,它就會把該文件下載下來。比如: html 、 pdf 、 png 等使用 window.open 是無法打開的。
另外一點,使用 window.open 會受到瀏覽器安全策略的限制,會靜默該行為。
window.location
使用 window.location.href ='xxx.zip' 或者 window.location='xxx.zip' 實現文件的下載; 但是該方法不僅具有 window.open 的限制,還會受到瀏覽器兼容性的影響。
a 標簽
還有一種處理方式:使用 H5 a 標簽 download 新特性,其是規定超鏈接下載的目標。比如
<a href="https://github.com/Yao-JSON/blog/archive/master.zip" download="blog"> Download ZIP </a>
該方法兼容性較好,而且交互體驗友好,不需要打開一個新的窗口,在當前窗口下實現下載。最具代表性的解決案例是:Github Docunload Zip ;
但是該方案僅適用於已知的服務器端靜態資源文件下載,在業務上很有局限性。通常在業務開發中,文件通常是后端生成動態的下載,所以以下才是正確的處理方式。
動態的創建 a 標簽
動態創建 a 標簽,實施下載;顧名思義,就是創建一個 a 標簽,添加 href 、 download 屬性,模擬用戶點擊,實現下載。 具體代碼如下:兼容()
const downloadFile = (url, fileName = '') => {
let eleLink = document.createElement('a');
eleLink.download = fileName;
eleLink.style.display = 'none';
eleLink.href = url;
// 受瀏覽器安全策略的因素,動態創建的元素必須添加到瀏覽器后才能實施點擊
document.body.appendChild(eleLink);
// 觸發點擊
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
};
export default downloadFile;
其他下載
如何下載 html 片段或者文本
import downloadFile from './downloadFile';
const debug = ['<a id="a"><b id="b">hey!</b></a>'];
const blob = new Blob(debug,{
type: 'text/html'
})
const url = URL.createObjectURL(blob);
downloadFile(url, 'index.html');
圖片是base64 如何實現下載
import downloadFile from './downloadFile';
const debug = ['base:...'];
const blob = new Blob(debug,{
type: 'text/html'
})
const url = URL.createObjectURL(blob);
downloadFile(url, 'index.html');
canvas 下載
import downloadFile from './downloadFile';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
...
...
...
const src = canvas.toDataURL('image/png')
downloadFile(src, 'canavs.png')
參考地址:https://juejin.cn/post/6844903703908990990
