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