前端结合 react axios 获取真实下载、上传进度
首页确保项目中使用了axios
axios ondownloadprogress中total总为零,content-length不返回?
点我查看 Axios Documention
npm i axios
yarn add axios
以下我们举例接口调用配置说明:
由于接口下载时,不确定文件下载时长,所以直接设置不限时
timeout: -1,
由于 axios 已提供下载与上传的回掉函数(callback),所以我们直接调用就好
import { useState } from "react"
type ProgressStatusType = "normal" | "active" | "success" | "exception"
interface TestReportState {
showProgressModal: boolean
downloadPercent: number
downloadStatus: ProgressStatusType
}
const [showProgressModal,setShowProgressModal] = useState<boolean>(false)
const [downloadPercent,setDownloadPercent] = useState<number>(0)
const [downloadStatus,setDownloadStatus] = useState<ProgressStatusType>("normal")
// 外层调用
const downloadFile = async (filename: string): Promise<void> => {
try {
setShowProgressModal(true)
setDownloadStatus("active")
const res = await downLoadFileTemp({ filename }, state)
setDownloadStatus("success")
downloadFileAction(filename, res)
} catch (error) {
setDownloadStatus("exception")
console.error("downloadFile->", error)
}
}
export const downLoadFile = (params: { filename: string }, setDownloadPercent:()=>void ): Promise<Blob> => {
return get(`api/getFile?${qs.stringify(params)}`, {
timeout: -1, // 不限时
onDownloadProgress: (progressEvent: ProgressEvent) => {
setDownloadPercent(calcProgress(progressEvent))
},
onUploadProgress: (progressEvent: ProgressEvent) => {
// Do whatever you want with the Axios progress event
},
})
}
为了提高代码互用性与可维护性所以将计算进度的逻辑做了封装
/**
* 计算进度条百分比
*/
export const calcProgress = (progressEvent: ProgressEvent): number => {
const { loaded = 0, total = 0 } = progressEvent || {}
return Math.ceil((loaded / total) * 100) || 0
}
你可能有疑惑 progressEvent 中所含有的字段,请看以下示例:
/**
* Events measuring progress of an underlying process, like an HTTP request (for an XMLHttpRequest, or the loading of the underlying resource of an <img>, <audio>, <video>, <style> or <link>).
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent)
*/
interface ProgressEvent<T extends EventTarget = EventTarget> extends Event {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/lengthComputable) */
readonly lengthComputable: boolean;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/loaded) */
readonly loaded: number;
readonly target: T | null;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/total) */
readonly total: number;
}
axios ondownloadprogress中total总为零,content-length不返回?
-
后端在header中加上content-length
- 如果使用了Gzip做了文件分块获取到的 content-length 也可能是不准确的,所以可以让后端将此信息新建一个字段解决 例如:
response header {
...
custom-content-length: 2040
}