前提:利用接口導出一個文件,前端會遇到的幾種情況壕翩。這里主要記錄一下文件流太大的情況
1. 導出接口直接給的文件流
- 文件不大的時候,我們直接使用a標簽交給瀏覽器來下載
function downOSSUrl(url) {
const a = document.createElement('a')
a.href = url
a.rel = 'noreferrer'
document.body.appendChild(a)
a.click()
a.remove()
}
- 文件大的時候,直接使用以上方式就不太合適莱坎,接口處理太慢了蛛蒙,點擊后頁面沒啥反應糙箍,還以為有bug。那就獲取狀態(tài)加個loading吧
// request 是封裝的axios牵祟。 主要是注明一下 responseType: 'blob'
this.exportLoading = true
request({ url:'exportURL', params, responseType: 'blob' }).then(res => {
this.exportLoading = false
if (res === 0) {
this.$message.warning(提示語)
}
}).catch(() => {
this.exportLoading = false
})
攔截一下axios深夯。 下面的鏈接超時時間timeout以及nginx的超時時間我們都改大一些
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
timeout: 300000 // request timeout
})
service.interceptors.response.use(
response => {
if (response.config.responseType === 'blob' && response.status === 200) {
if (response.data.size === 0) {
return 0
}
const filename = response.headers['content-disposition'].split(';')[1].split('=')[1]
const blob = new Blob([response.data])
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 創(chuàng)建下載的鏈接
downloadElement.href = href
downloadElement.download = filename // 下載后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 點擊下載
document.body.removeChild(downloadElement) // 下載完成移除元素
window.URL.revokeObjectURL(href) // 釋放掉blob對象
return
}
}
)
以上代碼可以看到兩個點
(1)response.data.size 長度為0 ,我這里直接返回0.
因為后端考慮到處理時間太長诺苹,機器負載問題咕晋,限制了一分鐘內(nèi)不能同時多次下載,直接拋錯收奔。當多次請求到后端時體現(xiàn)在接口返回內(nèi)容上掌呜,流的長度就是0,此時提示用戶:稍后再試
(2)當有信息的時候呢,那就是有兩種情況坪哄。
一種是包含錯誤信息或者提示信息质蕉, 一種是真正的文件信息。上面代碼只考慮了直接下載文件信息翩肌。
當和后端有約定要展示特定條件的提示信息時模暗,可以增加以下判斷。將流用 filereader
解析程json
if(response.headers['content-type'].includes('json')){
const fileReader = new FileReader()
fileReader.readAsText(response.data, 'utf-8')
fileReader.onload = function(res){
....
}
}
(3) 文件名從響應頭中的content-disposition拿到念祭,沒有的話兑宇,要后端導出
其實相比于直接用
a
標簽交給瀏覽器下載,這樣的請求后下載的棒卷,是直接寫入到瀏覽器內(nèi)存的顾孽,所以可以看到整個請求也包含了download
的時間,再到磁盤比规,才會在瀏覽器上看到進入了下載中心
2. 導出接口給的是有正常響應體若厚,result
是oss地址
,那拿到地址后再直接去a標簽
下載即可
3. 接口處理時間太長蜒什,出現(xiàn)504 gateway time-out
测秸,很明顯nginx
太久沒拿到服務端結果,給了前端504
。 設置nginx
代理響應時間
(1)上面有個
axios
請求超時的時間,以毫秒為單位霎冯。設置大點铃拇,這里超時是主動斷開了,但是后端還在處理沈撞。
(2)nginx 設置超時時間,單位是秒慷荔。可以設置在http
全局模塊缠俺,server
模塊显晶,或者是location
特定模塊。
location /api {
proxy_read_timeout 300; // 代理讀取超時時間
proxy_send_timeout 300; // 代理發(fā)送超時時間
proxy_connect_timeout 300; // 代理連接超時時間
}