文件上傳下載在業務開發中很是常見,尤爲在企業級應用中;實現圖片、報表類文件的下載居多。最近我有贊商品中心後臺商品批量改價功能模塊與堂食點單插件功能模塊中就遇到文件下載的需求。javascript
通常在文件下載的方式:html
window.open("htpp://127.0.0.1/test.rar");
複製代碼
使用 window.open
是能夠實現文件的下載,正常的 zip
、 rar
、 arj
等文件是可使用 window.open
打開的;window.open
可以打開的原理是讓我門用瀏覽器打開一個文件時,若是瀏覽器沒法解析,它就會把該文件下載下來。好比: html
、 pdf
、 png
等使用 window.open
是沒法打開的。java
另一點,使用 window.open
會受到瀏覽器安全策略的限制,會靜默該行爲。git
使用 window.location.href ='xxx.zip'
或者 window.location='xxx.zip'
實現文件的下載; 可是該方法不只具備 window.open
的限制,還會受到瀏覽器兼容性的影響。github
還有一種處理方式:使用 H5 a
標籤 download 新特性,其是規定超連接下載的目標。好比canvas
<a href="https://github.com/Yao-JSON/blog/archive/master.zip" download="blog">
Download ZIP
</a>
複製代碼
該方法兼容性較好,並且交互體驗友好,不須要打開一個新的窗口,在當前窗口下實現下載。最具表明性的解決案例是:Github Docunload Zip
;後端
可是該方案僅適用於已知的服務器端靜態資源文件下載,在業務上頗有侷限性。一般在業務開發中,文件一般是後端生成動態的下載,因此如下才是正確的處理方式。瀏覽器
動態建立 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;
複製代碼
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');
複製代碼
import downloadFile from './downloadFile';
const debug = ['base:...'];
const blob = new Blob(debug,{
type: 'text/html'
})
const url = URL.createObjectURL(blob);
downloadFile(url, 'index.html');
複製代碼
import downloadFile from './downloadFile';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
...
...
...
const src = canvas.toDataURL('image/png')
downloadFile(src, 'canavs.png')
複製代碼
實施案例: 服務器
github 歡迎 star