需求: 一個集成項目,從第三方平台拿到了文件地址:http://aa/videoname.mp4,前端做個點擊下載的功能
使用 a標簽 <a href=' http://aa/videoname.mp4'>下載</a> 來做, 直接點擊瀏覽器會播放此視頻文件,並非所期望的下載文件.
原因: a標簽的默認行為是鏈接跳轉進行預覽,而針對瀏覽無法預覽的文件,也可達到下載的效果. 顯然mp4是被瀏覽器識別了.
a標簽加上downlaod屬性后(download=下載時顯示的文件名),就可完成對href屬性鏈接文件的下載,但僅是限於同源文件,如果是非同源,download屬性會失效。我們本地開發時,web頁面地址是localhost:8080, 即便是部署到生產環境也只是http://bb, 顯然與文件地址http://aa/videoname.mp4不同源.
使用js直接請求 http://aa/videoname.mp4進行請求到Blob再轉換成本地url進行下載
1 const a = document.createElement("a"); 2 a.download = fileName; 3 a.href = window.URL.createObjectURL(blob) 4 document.body.appendChild(a); 5 a.click(); 6 document.body.removeChild(a)
上面這種下載方法相當於下載了兩遍, 非常慢,體驗極不友好.
解決方案: 使用前端項目工程的代理功能,達到同源效果
<a href=' http://aa/videoname.mp4'> 替換為 const fileUrl = 'http://aa/videoname.mp4' const downloadUrl ='/download'.concat(fileUrl) .substr(fileUrl .indexOf('/', 8))) <a href={downloadUrl} download={record.name}>下載</a>
且在代理文件中,將帶有 /download 的請求攔截,替換成真正的請求域名, 如我用的是umijs 代理配置文件/config/proxy.js:
'/download': { target: "http://aa", changeOrigin: true, pathRewrite: { '^/download': '', }, logLevel: DEV_PROXY_LOG_LEVEL, },
注: 生產環境下, 這種代理是不起作用的,可以用nginx進行代理.