摘要:對(duì)于通過(guò)去下載文件時(shí)跨域的問題有一個(gè)解決思路是自己寫一個(gè)代理服務(wù)代理服務(wù)負(fù)責(zé)在服務(wù)端下載文件并配置好跨域相關(guān)的信息然后請(qǐng)求走代理服務(wù)進(jìn)行下載。
0. 概述
文件下載是web應(yīng)用中很常見的場(chǎng)景,在瀏覽器中下載文件, 最基本的方式就是——在頁(yè)面內(nèi)隱藏iframe, 然后將文件下載地址加載到iframe中, 從而觸發(fā)瀏覽器的下載行為。 此外, html5引入a標(biāo)簽的download屬性, 也是一種下載方式。
下載
下面針對(duì)下載地址的Response Header、瀏覽器兼容性, 以及一些特殊case, 做一些說(shuō)明。
1. 怎樣的文件url才能觸發(fā)瀏覽器的下載行為?能觸發(fā)瀏覽器下載的url有兩類:
response header中指定了Content-Disposition為attachment,它表示讓瀏覽器把響應(yīng)體作為附件下載到本地 (一般Content-Disposition還會(huì)指定filename, 下載的文件默認(rèn)就是filename指定的名字)
response header中指定了Content-Type 為 application/octet-stream(無(wú)類型) 或者 application/zip(下載zip包時(shí))以及其它幾個(gè)不常見類型 (其中還有瀏覽器差異),其中 application/octet-stream表示http response為二進(jìn)制流(沒指定明確的type), 需要下載到本地, 由系統(tǒng)決定或者用戶手動(dòng)指定打開方式。
關(guān)于application/octet-stream的情況, 補(bǔ)充幾點(diǎn)
這種response, 由于沒有明確的type, 如果作為文件下載的話, 下載下來(lái)的文件將沒有文件名和拓展名(文件名直接取的url path的最后一坨)
如果不作為文件下載, 比如已知response body是一張圖片, 可以通過(guò)img標(biāo)簽來(lái)顯示圖片
下載下來(lái)的內(nèi)容, 只是缺少文件拓展名而已, 文件內(nèi)容是完整的, 如果知道它實(shí)際的拓展名, 手動(dòng)改了就能通過(guò)系統(tǒng)默認(rèn)的程序打開, 不改拓展名的話也能通過(guò)指定應(yīng)用程序的方式打開
關(guān)于response header的Content-Type, 補(bǔ)充幾點(diǎn)
首先要明確, Content-Type只是HTTP協(xié)議的部分, 不影響response body自身
Content-Type影響的是response的接收方(一般是瀏覽器), 對(duì)于瀏覽器而言, 它影響的是瀏覽器對(duì)響應(yīng)體的處理方式. 比如指定為application/zip, 瀏覽器就會(huì)用pdf閱讀器打開.
Content-Type之于瀏覽器, 就好比文件擴(kuò)展名之于操作系統(tǒng), 影響的默認(rèn)行為, 如果你指定了打開方式, 那么Content-Type就不起作用了. 比如, 你在服務(wù)端對(duì)圖片地址設(shè)置Content-Type為application/zip,但你在瀏覽器使用img標(biāo)簽(相當(dāng)于指定了打開方式)去加載, 照樣能正常加載圖片。
為什么上面說(shuō)的「Content-Type」還有「文件拓展名」對(duì)于文件自身沒有影響?
這里涉及到「文件格式協(xié)議」/「文件頭」等內(nèi)容, 待補(bǔ)充...
只要滿足上述「觸發(fā)瀏覽器自動(dòng)下載」的url, 就能通過(guò)iframe的形式.
一般的用法是在html中隱藏iframe, 然后在業(yè)務(wù)代碼中通過(guò)設(shè)置iframe的src來(lái)實(shí)現(xiàn)下載.
download兼容性
主流瀏覽器對(duì)于的特殊情況說(shuō)明:
Safari只支持「能觸發(fā)瀏覽器下載」的url
Firefox也只支持「能觸發(fā)瀏覽器下載」的url, 此外還有一個(gè)需要注意的地方——點(diǎn)擊a標(biāo)簽時(shí), 會(huì)觸發(fā)「瀏覽器離開當(dāng)前頁(yè)面」的行為, 解決這個(gè)問題的方式是「再搭配一個(gè)iframe, 將a標(biāo)簽的target指向這個(gè)iframe」,這樣就不會(huì)有頁(yè)面跳轉(zhuǎn)了
Chrome對(duì)于「不能觸發(fā)瀏覽器下載」的url, 也可以通過(guò)這種方式下載。
4. 用哪種方式對(duì)于下載來(lái)源完全由自己控制的業(yè)務(wù)場(chǎng)景(意味著Response Header是統(tǒng)一的), 推薦
瀏覽器兼容性好
如果跟「下載」操作一起還有一系列操作按鈕, 可以統(tǒng)一代碼結(jié)構(gòu). (不然的話就「下載」操作按鈕是用的a標(biāo)簽, 其它按鈕不是)
對(duì)于下載來(lái)源不受控制的場(chǎng)景, 則可選擇的方式
在chrome下, 比iframe方式兼容的下載場(chǎng)景多
番外. 迫不得已, 花式的下載方式構(gòu)想這樣的場(chǎng)景, 對(duì)于Response Header中Content-Type為image/png的圖片url,能怎樣下載呢?(這里不考慮‘右鍵另存為’)
對(duì)于Chrome瀏覽器,使用的方式可以下載, 但其他瀏覽器怎么辦呢?
如果要強(qiáng)行下載這張圖片的話, 想了下, 也是有辦法的
代碼中構(gòu)造xhr請(qǐng)求該圖片地址, 以Blob的形式接收Response, 然后轉(zhuǎn)換成DataURL, 將DataURL的頭部設(shè)置為image/octet-stream, 然后就可通過(guò)以上
上面構(gòu)造xhr請(qǐng)求的方式存在CORS問題, 如果不滿足跨域條件, 簡(jiǎn)單點(diǎn)的替換方案是使用img標(biāo)簽加載圖片,然后畫到canvas上, 然后導(dǎo)出為DataURL, 后續(xù)同上...
一些備注下載文件時(shí), 在瀏覽器devTools的Network面板無(wú)法查看下載請(qǐng)求的http相關(guān)信息, 如果你想觀察上面提到的Response Header中相關(guān)的信息, 可通過(guò)shell指令curl對(duì)下載地址發(fā)送HEAD請(qǐng)求, 以查看Response Header.
關(guān)于各種case的驗(yàn)證, 可自己簡(jiǎn)單寫一個(gè)http服務(wù), 設(shè)置不同的Response Header, 然后打開瀏覽器驗(yàn)證。
對(duì)于通過(guò)xhr去下載文件時(shí)跨域的問題, 有一個(gè)解決思路是, 自己寫一個(gè)代理服務(wù), 代理服務(wù)負(fù)責(zé)在服務(wù)端下載文件, 并配置好跨域相關(guān)的信息, 然后xhr請(qǐng)求走代理服務(wù)進(jìn)行下載。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/54402.html
摘要:對(duì)于通過(guò)去下載文件時(shí)跨域的問題有一個(gè)解決思路是自己寫一個(gè)代理服務(wù)代理服務(wù)負(fù)責(zé)在服務(wù)端下載文件并配置好跨域相關(guān)的信息然后請(qǐng)求走代理服務(wù)進(jìn)行下載。 0. 概述 文件下載是web應(yīng)用中很常見的場(chǎng)景,在瀏覽器中下載文件, 最基本的方式就是——在頁(yè)面內(nèi)隱藏iframe, 然后將文件下載地址加載到iframe中, 從而觸發(fā)瀏覽器的下載行為。 此外, html5引入a標(biāo)簽的download屬性, ...
摘要:說(shuō)明本文主要講述了的文件系統(tǒng)的小,邏輯不復(fù)雜,主要就是把上的一個(gè)文件下載到本地,和下載到中。寫驅(qū)動(dòng)由于沒有驅(qū)動(dòng),需要自定義下在中寫上名為的驅(qū)動(dòng)同時(shí)在注冊(cè)下該就行。執(zhí)行命令后,顯示上文件從上下載到上的文件該邏輯簡(jiǎn)單,但很好玩。 說(shuō)明:本文主要講述了Laravel的文件系統(tǒng)Filesystem的小Demo,邏輯不復(fù)雜,主要就是把Dropbox上的一個(gè)文件下載到本地local,和下載到AWS...
摘要:分布式爬蟲框架詳解隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展與應(yīng)用的普及,網(wǎng)絡(luò)作為信息的載體,已經(jīng)成為社會(huì)大眾參與社會(huì)生活的一種重要信息渠道。下載器中間件位于引擎和下載器之間的框架,主要是處理引擎與下載器之間的請(qǐng)求及響應(yīng)。 scrapy-redis分布式爬蟲框架詳解 隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展與應(yīng)用的普及,網(wǎng)絡(luò)作為信息的載體,已經(jīng)成為社會(huì)大眾參與社會(huì)生活的一種重要信息渠道。由于互聯(lián)網(wǎng)是開放的,每個(gè)人都可以在網(wǎng)絡(luò)上...
摘要:目標(biāo)是探索是否能夠加快頁(yè)面首屏速度。實(shí)驗(yàn)組瀏覽器支持,本次時(shí),進(jìn)行初始化。從上面的直觀對(duì)比可以看出,個(gè)指標(biāo),組的分位值都略微大于組的分位值,差距在幾十毫秒左右。最終,我也沒有采用來(lái)優(yōu)化首屏速度。 寫在前面 本文首發(fā)于公眾號(hào):符合預(yù)期的CoyPan 不久之前,我簡(jiǎn)單探索了service worker在一個(gè)活動(dòng)運(yùn)營(yíng)頁(yè)面中的應(yīng)用,可以參考我之前的這篇文章: service worker輕度探...
閱讀 2624·2021-11-22 12:01
閱讀 1141·2021-11-15 11:37
閱讀 3735·2021-09-22 14:59
閱讀 1786·2021-09-04 16:45
閱讀 1419·2021-09-03 10:30
閱讀 1063·2021-08-11 11:18
閱讀 2497·2019-08-30 10:53
閱讀 2047·2019-08-29 15:13