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