1. 程式人生 > >如何用ajax下載文件

如何用ajax下載文件

err ont 完成 二進制文件 -o formdata 全部 ray 學習資料

引子

在HTML5沒來之前,瀏覽器想要下載文件,可能有這麽幾種方式:

  1. 借助a標簽,<a href="學習資料.xlsx"></a>

  2. window.location = ‘學習資料.xlsx‘

  3. 借助瀏覽器插件,如flash等(沒考證過)

除了第三外,前兩種方法有個缺點,就是無法知道下載是否完成,因為瀏覽器沒有給出相關的事件。但是,自從有了Blob,fetch, xhr2這些好用的API之後,ajax下載文件(小文件)就變得可行了,核心原因就在於Blob和ArrayBuffter這些API提供給了瀏覽器操作二進制文件的能力。接下來就開始我的表演

1. fetch方法

fetch優點有很多,比如基於promise,寫起來直觀易懂,缺點是IE,包括IE11全部不支持。
使用時要註意一點是,fetch請求時默認不會帶上cookie,如果你的api是在登錄後才能訪問,記得手動設置 credentials選項。下面是下載一個文件的代碼:


      fetch(‘學習資料.xlsx‘, {
        method: ‘GET‘,
        credentials: "same-origin"// 帶上cookie
      })
      .then(res => res.blob())

      .then(blob => {
        saveAs(blob) //fileSaver.js中的方法
      })

從上面可以看出,調用fetch時會返回一個promise,當promise resolve時,會傳出一個Response的實例(res),這個res除了有statusstatusText

ok 這幾個屬性用於獲取服務器相應的狀態值外,還有幾個炫酷的方法,正式這幾個方法,使瀏覽器可以請求的數據類型不再局限於文本,他們是:

res.blob() //返回值是一個promise,promise resolve後會拿到一個blob對象
res.json() //返回值是一個promise,promise resolve後會拿到一個json對象,無需再調用JSON.parse
res.text() //返回值是一個promise,promise resolve後會拿到一個字符串
res.formData() //返回值是一個promise,promise resolve後會拿到一個表單數據對象(formData)

所以拿到blob後,接下來就是觸發瀏覽器的下載了,這裏調用了一個saveAs函數,它來自FileSaver.js,一個不用請求api也可以觸發瀏覽器下載動作的庫,它接受一個blob對象,和一個可選的文件名稱參數,就能觸發下載動作。

2.xhr2方法

xhr2的兼容性比fetchAPI要好,兼容到IE10,它沒有向fetch一樣把難用的xhr推翻重做,而是做了一些有用的擴展,比如xhr.responseType,在發起請求前,通過設置這個屬性,可以使瀏覽器對返回的數據進行處理,就像res的那些有用的方法一樣。xhr.responseType可以取下列值:

  "arraybuffer",
  "blob",
  "document",
  "json",
  "text"

沒錯,就是和上面的res的那些方法殊途同歸。當請求數據返回時,你可以從xhr.response拿到相應的數據。為什麽不是res.responseText呢?很明顯這是xhr1時期的,從這個屬性只能拿到字符串,是滿足不了我們的需求的。

接下來的事情就跟上面一樣了,照例貼一下代碼:

      var xhr = new XMLHttpRequest();
      xhr.responseType = ‘blob‘;
      xhr.open(‘GET‘, url, true);
      xhr.onload = function(){
          var res = xhr.response;
          if(res){
            saveAs(res, filename);
          }
      }
      xhr.send();

到這裏,你就可以從容掌握文件下載的狀態了。最後再啰嗦一句,xhr.onload也是xhr2增加的事件,有了它,再也不想用xhr.onReadyStateChange了。其他新增的事件還有‘onprocess‘, ‘onerror‘, ‘onabort‘, ‘onloadstart‘,‘onloadend‘, ‘ontimeout‘。(完)

如何用ajax下載文件