做百度網(wǎng)站百度關鍵詞優(yōu)化的意思
用 JavaScript 的 axios 實現(xiàn)文件下載功能,咱們要分幾個步驟來搞定它!最主要的部分是處理 二進制數(shù)據(jù),可以生成一個進度檢測,然后把它保存為文件。
- 文件名的獲取
- 二進制數(shù)據(jù)獲取
- 創(chuàng)建下載鏈接
const axios = require('axios');const getFileNameFromContentDisposition = (contentDisposition) => {const fileNameMatch = contentDisposition && contentDisposition.match(/filename="?([^"]+)"?/);return fileNameMatch ? fileNameMatch[1] : null;
};const getFileNameFromUrl = (fileUrl) => {return fileUrl.split('/').pop();
};const downloadFile = async (fileUrl, defaultFileName = 'downloaded-file') => {try {const response = await axios({url: fileUrl,method: 'GET',responseType: 'blob', // 以二進制方式接收數(shù)據(jù)onDownloadProgress: (progressEvent) => {// progressEvent 包含了下載進度信息const total = progressEvent.total; // 文件總大小const loaded = progressEvent.loaded; // 已經(jīng)下載的部分// 計算進度百分比const percentage = Math.floor((loaded / total) * 100);// 顯示進度(可替換為實際的進度條)console.log(`下載進度:${percentage}%`);}});// 獲取文件名let fileName = getFileNameFromContentDisposition(response.headers['content-disposition']) || getFileNameFromUrl(fileUrl) || defaultFileName;// 創(chuàng)建 Blob 對象const blob = new Blob([response.data], { type: response.headers['content-type'] });// 創(chuàng)建 Blob URLconst blobUrl = window.URL.createObjectURL(blob);// 創(chuàng)建 <a> 元素并觸發(fā)下載const link = document.createElement('a');link.href = blobUrl;link.download = fileName;// 將 <a> 元素添加到 DOM 并觸發(fā)點擊document.body.appendChild(link);link.click();// 移除 <a> 元素document.body.removeChild(link);// 釋放 Blob URLwindow.URL.revokeObjectURL(blobUrl);} catch (error) {console.error('文件下載失敗: ', error);}
};// 調(diào)用下載函數(shù),傳入文件URL
downloadFile('https://example.com/path/to/your/file.pdf');
從代碼優(yōu)化和健壯性角度出發(fā),我們可以把這三種文件名獲取方式結(jié)合起來,優(yōu)先從響應頭中提取文件名,然后如果沒有Content-Disposition
頭,再從 URL 提取文件名,最后可以提供一個默認文件名作為兜底方案。此外,考慮到代碼可讀性和可維護性,上面代碼做一些清晰的封裝與優(yōu)化處理。
-
文件名獲取邏輯封裝:
getFileNameFromContentDisposition
:專門用于從Content-Disposition
頭部提取文件名,使用正則匹配,考慮了有引號和沒有引號的情況。getFileNameFromUrl
:用于從 URL 提取文件名,確保從路徑最后一部分獲取到文件名。- 優(yōu)先級:先從
Content-Disposition
獲取文件名,如果沒有,再從 URL 提取,最后使用默認文件名。
-
默認文件名:
- 提供了
defaultFileName
參數(shù),確保當無法從響應頭和 URL 獲取文件名時,仍然有一個合理的文件名用于下載。
- 提供了
-
異常處理:
- 使用
try-catch
包圍整個下載過程,確保即使出現(xiàn)網(wǎng)絡或其他問題,錯誤也能被捕獲并輸出到控制臺,而不會影響頁面的其他功能。
- 使用
-
內(nèi)存管理:
- 確保
window.URL.revokeObjectURL(blobUrl)
在文件下載后被調(diào)用,釋放 Blob URL,防止內(nèi)存泄漏。
- 確保
健壯性和可擴展性:
- 健壯性:我們確保了即使某個步驟失敗,代碼也能繼續(xù)運行。文件名無法從響應頭或 URL 獲取時,始終有一個默認文件名兜底。
- 可擴展性:如果未來需要支持更多的文件名獲取邏輯或更復雜的響應頭處理,只需修改或添加新的獲取方式即可,而不會影響整體代碼結(jié)構(gòu)。
為什么可以立即移除 <a>
元素?
點擊事件:link.click()
觸發(fā)后,瀏覽器會處理下載請求,下載任務已經(jīng)在后臺進行。<a>
元素的點擊只是用來啟動這個過程。
DOM
操作與事件的異步性:瀏覽器在處理用戶點擊和下載之間有一定的時間差,移除 <a>
元素是在 click
事件完成后進行,不會影響已經(jīng)發(fā)出的下載請求。
為什么不用關注文件類型
下載文件的前置條件中不依賴于文件的具體類型,實際上,代碼對文件類型的處理是比較通用的。這是通過以下幾個方面實現(xiàn)的:
1. 響應類型的設置
- 在 Axios 請求中,我們將
responseType
設置為'blob'
,這意味著無論文件類型是什么,瀏覽器都將其作為 Blob 對象處理。Blob 可以表示二進制數(shù)據(jù),而不關心其具體的內(nèi)容類型。
2. Content-Type 的使用
- 在創(chuàng)建 Blob 時,我們根據(jù)響應頭中的
Content-Type
來設置 Blob 的 MIME 類型。這使得文件在下載時能夠被瀏覽器正確識別和處理:const blob = new Blob([response.data], { type: response.headers['content-type'] });
3. 文件名的獲取
- 文件名的獲取邏輯同樣不依賴于文件類型。我們根據(jù)
Content-Disposition
頭部或 URL 提取文件名。這樣無論是 PDF、圖片、文本文件還是其他任何類型的文件,代碼都能正確生成文件名并完成下載。
4. 下載時的文件處理
- 瀏覽器會根據(jù) Blob 的 MIME 類型和下載時提供的文件名來決定如何處理文件。例如,對于 PDF 文件,瀏覽器會使用 PDF 閱讀器打開它,而對于圖片文件則會直接展示。
注意事項
-
特殊文件類型處理:雖然以上代碼可以處理多種類型的文件,但某些文件(如 HTML 文件)可能會受到瀏覽器的默認行為影響。例如,某些文件可能會直接在瀏覽器中打開,而不是下載。這是由瀏覽器對特定 MIME 類型的處理決定的,無法通過代碼控制。
-
服務器的配置:如果服務器沒有正確設置
Content-Disposition
頭部,或者對某些文件類型沒有指定 MIME 類型,可能會導致文件下載或命名不正確。因此,確保服務器正確配置是關鍵。🚀