91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

通過JavaScript下載文件到本地的方法(單文件)

發布時間:2020-10-09 15:48:30 來源:腳本之家 閱讀:870 作者:小閑 欄目:web開發

最近在做一個文件下載的功能,這里把做的過程中用的技術和坑簡要總結下。

1. 單文件下載(a標簽)

同源單文件

針對單文件的情況下,同源的文件,可以通過 < a> 標簽的 download 屬性下載文件

 const elt = document.createElement('a');
 elt.setAttribute('href', url);
 elt.setAttribute('download', 'file.png');
 elt.style.display = 'none';
 document.body.appendChild(elt);
 elt.click();
 document.body.removeChild(elt);

但是這個方案并不適用于非同源的資源,此時它相當于普通的超鏈接,點擊會跳轉到資源頁面,而不是下載。

非同源圖片

如果不存在CORS問題, 可以借助Blob實現下載(構造xhr請求文件地址, 以Blob的形式接收Response):

function downloadWithBlob(url) {
 fetch(url).then(res => res.blob().then(blob => {
  var a = document.createElement('a');
  var url = window.URL.createObjectURL(blob);
  var filename = 'file.png';
  a.href = url;
  a.download = filename;
  a.click();
  window.URL.revokeObjectURL(url);
 }));
}

如果存在CORS問題,可以考慮使用 canvas 將圖片轉換成 base64 編碼之后再通過 標簽的 download 屬性下載

function downloadPic(url) {
 const img = new Image;
 const canvas = document.createElement('canvas');
 const ctx = canvas.getContext('2d');
 img.onload = function() {
  canvas.width = this.width;
  canvas.height = this.height;
  ctx.drawImage(this, 0, 0);

  const elt = document.createElement('a');
  elt.setAttribute('href', canvas.toDataURL('image/png'));
  elt.setAttribute('download', 'file.png');
  elt.style.display = 'none';
  document.body.appendChild(elt);
  elt.click();
  document.body.removeChild(elt);
 };
 img.crossOrigin = 'anonymous';
 img.src = url;
}

2. 單文件下載(iframe)

iframe方式是在頁面內隱藏iframe, 然后將下載地址加載到iframe中, 從而觸發瀏覽器的下載行為

 const iframe = document.createElement('iframe');
 iframe.src = url;
 iframe.style.display = 'none';
 document.body.appendChild(iframe);

但是這里發現,即使是同域的圖片,也無法完成下載,這是為啥呢?

這里就有個上面的a鏈接下載沒有提到的問題:什么樣的鏈接才能觸發瀏覽器的下載:

url如何觸發瀏覽器自動下載

一個url能否觸發瀏覽器自動下載,主要看該請求響應頭response header是否滿足,一般是看Content-Disposition和Content-Type這兩個消息頭:

  • response header中指定了Content-Disposition為attachment,它表示讓瀏覽器把消息體以附件的形式下載并保存到本地 (一般還會指定filename, 下載的文件名默認就是filename)
  • response header中指定了Content-Type 為 application/octet-stream(無類型) 或 application/zip(zip包時)等等。(其中 application/octet-stream表示http response為二進制流(沒指定明確的type), 用在未知的應用程序文件,瀏覽器一般不會自動執行或詢問執行。瀏覽器會像對待 設置了HTTP頭Content-Disposition 值為 attachment 的文件一樣來對待這類文件)

只要url滿足上述觸發的要求,那么都可以通過iframe的形式來下載

3. 代理服務處理下載

如果后端自己也能控制的話,或者后端能配合的話,可以寫一個代理服務,在后端去請求文件數據,然后設置好相應的response header, 然后前端請求代理服務來做下載。

前端(假設代理服務接口是http://exampale.com/download):

 const downloadUrl = 'http://exampale.com/download?url=' + encodeURIComponent(url) + '&name=xxx';
 const elt = document.createElement('a');
 elt.setAttribute('href', downloadUrl);
 elt.setAttribute('download', 'file.png');
 ... 

后端

const url = decodeURIComponent(req.query.url);
http.get(url, (response) => {
 res.setHeader('Content-disposition', 'attachment;filename=' + req.query.name);
 res.setHeader('Content-type', 'application/octet-stream');
 response.pipe(res);
});

單文件的處理先寫到這里,多文件的下載下篇在寫。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤翔县| 奉化市| 双牌县| 舞钢市| 黑水县| 大姚县| 高安市| 磴口县| 吉木萨尔县| 墨江| 达孜县| 全南县| 屏东县| 马山县| 门源| 张家川| 广汉市| 大连市| 惠水县| 饶阳县| 华安县| 西林县| 四川省| 德令哈市| 桃园县| 淄博市| 金坛市| 蒙阴县| 莱阳市| 长子县| 双江| 遂宁市| 宁陵县| 泰安市| 西乌珠穆沁旗| 临安市| 庆城县| 临澧县| 辽源市| 隆德县| 大同市|