前端结合 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不返回?

  1. 后端在header中加上content-length
  2. 如果使用了Gzip做了文件分块获取到的 content-length 也可能是不准确的,所以可以让后端将此信息新建一个字段解决 例如:
response header {
	...
	custom-content-length: 2040
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值