Vue 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;
}

如果其他问题可添加QQ 2697604576,一起探讨前端。

猜你喜欢

转载自blog.csdn.net/ShunxinLive/article/details/112919648