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