前端因爲安全方面的因素,不能直接對文件進行寫操做。可是在實際的業務需求中,不免會遇到各類各樣文件的下載、預覽。 若是服務端下載文件是以流的形式傳遞到前端,前端一般是將流轉換爲objectURL
,借用a
標籤的download
屬性,進行文件下載。可是有時候會遇到下載文件處理失敗的場景,這樣服務端消息的返回格式再也不是流,而是json
,此時雖然前端能夠正常導出文件,可是文件內容是服務端返回的消息,處置不怎麼穩當,這個時候,能有讀取流的方法就行了。本文簡要概述下,前端讀取二進制流的方法。前端
普通的二進制文件下載:首先須要將請求頭的response-type
設置爲blob
,其次,在接收到響應消息時,能夠調用如下方法。json
function download(blob) {
// 建立一個blob連接
let url = URL.createObjectURL(blob)
let a = document.createElement('a')
a.setAttribute('download', url)
a.href=ur;
a.style.display = 'none'
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
// 每次調用URL.createObjectURL,都會建立一個新的URL對象,瀏覽器內存中會保持對該對象的引用
// 只有在document銷燬時,纔會釋放此部份內存
// 在考慮性能的狀況下,在url使用結束後,最好釋放此部份內存
URL.revokeObjectURL(url)
}
複製代碼
上述只是二進制流文件通常的下載方式,當服務端傳回的響應類型content-type=application/json
時,咱們仍以二進制流的方式去解析處理,會致使導出文件內容出現問題,好比Excel中,內容爲服務端響應的消息,所以,咱們在處理服務器響應內容時,須要作下前置的攔截。瀏覽器
var debug = { hello: "world" };
var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'})
複製代碼
blob
內容的讀取,主要有兩種方式,FileReader和Response。安全
FileReader
顧名思義,這個對象主要就是用來讀取文件內容,兼容性比較好,有如下幾種讀取內容格式:readAsArrayBuffer
、readAsBinaryString
、readAsDataURL
、readdAsText
。FileReader
讀取方法主要以下所示:bash
var reader = new FileReader()
reader.addEventListener('loadend', function (e) {
// 輸出字符串 {hello: world}
console.log(e.target.result)
})
reader.readAsText(blob)
複製代碼
Response
是Fetch API
的一個接口,呈現的是對一次請求數據的響應。瀏覽器兼容性比FileReader
要差點,支持Chrome 42+
、FireFox 39+
。服務器
Response
實例化app
let myResponse = new Response(body, init)
複製代碼
body
Blob
BufferSource
FormData
URLSearchParams
USVString
init
status
statusText
headers
Response
實現了body
接口,因此,在實例化Response
時,能夠調用Body.blob()
、body.formData()
、body.json()
、body.text()
序列化返回值,返回值是一個Promise
。具體實現方法以下所示:性能
var blobReader = new Response(blob).json()
blobReader.then(res => {
console.log(res)
})
複製代碼
有了解析服務器返回值的方法,咱們在下載文件時,就能夠多判斷服務器返回值的content-type
,若是返回值不是blob
,咱們能夠作一些自定義處理。ui