這里給大家分享我在網(wǎng)上總結出來的一些知識,希望對大家有所幫助
前端涉及到的文件下載還是很多應用場景的,那么前端文件下載有多少種方式呢?每種方式有什么優(yōu)缺點呢?下面就來一一介紹。
1. 使用 a 標簽下載
通過a
標簽的download
屬性來實現(xiàn)文件下載,這種方式是最簡單的,也是我們比較常用的方式,先來看示例代碼:
<a?>下載</a>
就上面的這個示例,我們點擊下載,發(fā)現(xiàn)是跳轉到了百度的首頁,并沒有真的下載文件。
因為a
標簽下載只能下載同源
的文件;如果是跨域
的文件,比如圖片、音視頻等媒體文件等都無法使用上面的a
標簽方式下載。
上面的代碼是直接通過書寫a
標簽來實現(xiàn)文件下載;我們也可以通過js
來實現(xiàn),代碼如下:
const?a?=?document.createElement('a') a.href?=?'http://www.baidu.com' a.download?=?'baidu.html' a.click()
效果和上面的一樣,都是跳轉到百度的首頁,沒有下載文件。
這里的重點是a
標簽的download
屬性,這個屬性是HTML5
新增的。
它的作用是指定下載的文件名,如果不指定,那么下載的文件名就會根據(jù)請求內容的Content-Disposition
來確定,如果沒有Content-Disposition
,那么就會使用請求的URL
的最后一部分作為文件名。
2. 使用 window.open 下載
上面使用a
標簽的案例也可以通過window.open
來實現(xiàn),效果是一樣的,代碼如下:
window.open('http://www.baidu.com',?'_blank')
這里的_blank
是指定用瀏覽器新窗口打開鏈接;如果不指定,那么就會在當前頁面打開。
同樣a
標簽的download
屬性也是可以使用的,代碼如下:
window.open('http://www.baidu.com',?'_blank',?'download=baidu.html')
當然這種方式也是有缺陷的,對比于a
標簽,window.open
方式不能下載.html
、.htm
、.xml
、.xhtml
等文件;因為這些文件會被當成html
文件來處理,所以會直接在當前頁面打開。
同樣也不能下載跨域
的文件,這個是window.open
實現(xiàn)下載原理決定的。
3. 使用 location.? 下載
以下可以實現(xiàn)頁面跳轉的屬性,都可以實現(xiàn)文件下載
3.1 location.href
// 這個方式和window.open是一樣的 location.href?=?'http://www.baidu.com'
這種方式擁有window.open
的所有缺陷,所以不推薦使用,這里只當作了解,所以不做過多的講解。
3.2 location.assign
location.assign('http://www.baidu.com')
3.3 location.replace
location.replace('http://www.baidu.com')
3.4 location.reload
location.reload('http://www.baidu.com')
location.reload
是有點特殊的,它的作用是重新加載當前頁面,但是它也可以接受一個參數(shù),這個參數(shù)就是要跳轉的頁面,所以也可以實現(xiàn)文件下載。
當然同location.href
一樣,這些方式的缺點都一樣,同時還有屬于每個屬性自身的特性,這里只當拓展知識,不做過多的講解。
4. XMLHttpRequest
這種方式就是我們常說的ajax
下載,包括Axios
、Fetch
等,代碼如下:
const?xhr?=?new?XMLHttpRequest() xhr.open('GET',?'http://www.baidu.com') xhr.send() xhr.onload?=?function?()?{ const?blob?=?new?Blob([xhr.response],?{?type:?'text/html'?}) const?a?=?document.createElement('a') a.href?=?URL.createObjectURL(blob) a.download?=?'baidu.html' a.click() }
這里關于XMLHttpRequest
相關的知識就不做展開了,只講和文件下載相關的部分。
上面代碼主要的邏輯是當我們的請求成功后,我們會拿到響應體Response
,這個Response
就是我們要下載的內容。
然后我們把它轉換成Blob
對象,通過URL.createObjectURL
來創(chuàng)建一個URL
,最后使用a
標簽的download
屬性來實現(xiàn)文件下載。
5.1 Blob 對象
下面是MDN
對Blob
對象的定義:
Blob
對象表示一個不可變、原始數(shù)據(jù)的類文件對象。
Blob
的數(shù)據(jù)可以按文本或二進制的格式進行讀取,也可以轉換成ReadableStream
來用于數(shù)據(jù)操作。
Blob
表示的不一定是JavaScript
原生格式的數(shù)據(jù)。
File
接口基于Blob
,繼承了Blob
的功能并將其擴展以支持用戶系統(tǒng)上的文件。
Blob
對象是html5
新增的對象,它的作用是用來存儲二進制數(shù)據(jù)的,比如圖片、視頻、音頻等,它的使用方法如下:
/** ?*?@param?{Array}?array?二進制數(shù)據(jù) ?*?@param?{Object}?options?配置項 ?*?@param?{String}?options.type 文件類型,它代表了將會被放入到 blob 中的數(shù)組內容的 MIME 類型。 ?*?@param?{String}?options.endings 用于指定包含行結束符\n的字符串如何被寫入。默認為transparent,表示不會修改行結束符。還可以指定為native,表示會將\n轉換為\r\n。 ?*/ const?blob?=?new?Blob([],?{?type:?''?})
Tips:需要關注的是type
屬性,默認情況下, Blob
對象是沒有type
屬性的,那么這個Blob
就是一個無類型的Blob
,文件不會損毀,但是無法被正常識別。
5.2 URL.createObjectURL
下面是MDN
對 URL.createObjectURL
方法的定義:
URL.createObjectURL()
靜態(tài)方法會創(chuàng)建一個DOMString
,其中包含一個表示參數(shù)中給出的對象的URL
。
這個URL
的生命周期和創(chuàng)建它的窗口中的document
綁定。
這個新的URL
對象表示指定的File
對象或Blob
對象。
這個方法是用來創(chuàng)建一個URL
的,它的作用是把一個Blob
對象轉換成一個URL
,這個URL
可以用來下載文件,也可以用來預覽文件,代碼如下:
const?url?=?URL.createObjectURL(blob)
這里需要注意的是,這個URL
的生命周期和創(chuàng)建它的窗口中的document
綁定。
也就是說,當我們的document
被銷毀后,這個URL
就會失效,所以我們需要在合適的時機銷毀它。
代碼如下:
URL.revokeObjectURL(url)
回到我們剛才下載的問題,我們是通過Blob
對象來解決,但是我們的type
屬性是寫死的,如果在文件類型是確定的情況下是沒問題的。
但是如果這個接口就是下載文件的接口,文件可能是各種類型的,我們應該怎么處理?
這里的沒有正確答案,第一個可以和接口提供者進行協(xié)商,協(xié)商方案是不確定的;第二就是通過Response
的header
來獲取文件的type
,也是我們要講的:
const?type?=?response.headers['content-type'] const?blob?=?new?Blob([response.data],?{?type?})
這里我們通過Response
的header
來獲取type
,然后再創(chuàng)建Blob
對象,這樣就可以正確的下載文件了。
其實content-type
也可能是application/octet-stream
,這個時候我們就需要通過file-type
來獲取文件的type
了。
下面的代碼是通過file-type
來獲取文件的type
:
import?{fileTypeFromStream}?from?'file-type'; const?type?=?await?fileTypeFromStream(response.body); const?blob?=?new?Blob([response.data],?{?type?})
5. 總結
上面的方案這么多,其實最終還是落到a
標簽上,所以不管是通過瀏覽器的內置行為進行下載,還是通過ajax
進行下載,文件下載的最終還是瀏覽器的行為。文章來源:http://www.zghlxwxcb.cn/news/detail-546116.html
本文轉載于:
https://juejin.cn/post/7254143696483991611
如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-546116.html
到了這里,關于記錄--盤點前端實現(xiàn)文件下載的幾種方式的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!