Axios 切片上传文件含实时进度

切片上传一般用于大型文件上传,切成多个部分分开上传。

整体实现思路:


  1. 预先设置切片大小。
  2. 计算总切片次数
  3. 循环调用上传
import axios from 'axios';

/**
 * 请求参数封装为 FormData 对象
 * @param params 参数
 * @returns {FormData}
 */
const packageFormData = (params) => {
  const data = new FormData();
  Object.keys(params).forEach(function(key) {
    data.append(key, params[key]);
  });
  return data;
}

/**
 * 上传文件
 * @param options 配置参数
 * @param options.url 上传接口地址
 * @param options.params 请求参数
 * @param options.file File文件对象
 * @param options.onUploadProgress 上传进度事件
 * @param options.filename File文件键名,默认 file
 * @returns {Promise}
 */
export const uploadFile = (options) => {
  const params = options.params || {};  // 没有参数默认为空JSON对象
  params[options.filename || 'file'] = options.file;  // 没有规定file键名,默认为file
  const axiosOptions = {
    url: options.url,
    method: 'post',
    data: packageFormData(params)
  };
  // 判断是否需要上传进度反馈事件
  if (options.onUploadProgress) axiosOptions.onUploadProgress = options.onUploadProgress;
  return axios(axiosOptions);
}

/**
 * 切片上传
 * @param options 配置参数
 * @param options.url 上传接口地址
 * @param options.params 请求参数
 * @param options.file File文件对象
 * @param options.onUploadProgress 上传进度事件
 * @param options.filename File文件键名,默认 file
 * @returns {Promise<[]>}
 */
export async function uploadSection (options) {
  const sectionSize = 1 * 1024 * 1024; // 切片大小,超过该值将进行切片上传,字节(b)单位
  const sectionTotal = Math.ceil(options.file.size / sectionSize);  // 切片次数
  const fileSize = options.file.size; // 文件大小
  const results = []; // 切片结果返回集
  for(let i = 0; i < sectionTotal; i++) {
    const startSize = i * sectionSize;  // 切片开始位置
    // 切片结尾位置,判断如果是最后一次直则是文件大小
    const endSize = i === sectionSize - 1 ? fileSize : (i + 1) * sectionSize;
    const new_options = {...options};  // 复制原有的 options
    new_options.file = options.file.slice(startSize, endSize);
    if (options.onUploadProgress) {
      new_options.onUploadProgress = (progressEvent) => {
        options.onUploadProgress({
          loaded: startSize + progressEvent.loaded,
          total: fileSize
        });
      };
    }
    results.push(await uploadFile(new_options));
  }
  return results;
}

// 调用方法
uploadSection({
	url: '上传地址',
	params: {},	// 请求携带的参数
	file: file,	// 上传的文件对象
	onUploadProgress: (event) => {
		console.log('已上传进度:', event.loaded, '总大小:', event.total)
	},
	filename: 'file',	// File文件键名
})

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺芯技术猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值