Vue3+axios+.Net使用分片上传

Vue3+axios+.Net使用分片上传

前端代码

在ApiService.cs中增加方法

//上传文件
public static async uploadFile(file){
  const chunkSize = 1024 * 1024; // 1MB 每1mb分片
  const totalChunks = Math.ceil(file.size / chunkSize);
  let key='';

  let tag=true;
  let url='';//文件上传的结果
  for (let i = 0; i < totalChunks; i++) {
    if (!tag){
      continue;
    }
    const start = i * chunkSize;
    const end = Math.min(file.size, start + chunkSize);
    const chunk = file.slice(start, end);

    // Create FormData object and append chunk data
    const formData = new FormData();
    formData.append('file', chunk, file.name);
    formData.append('name', file.name);
    formData.append('key', key);
    formData.append('chunk', i.toString());
    formData.append('chunks', totalChunks.toString());

    // Make POST request using Axios
    await axios.post('/api/test/files', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    }).then(({ data }) => {
      key = data.key as string;
      if (i == (totalChunks-1)){
        if (import.meta.env.VITE_APP_API_URL != "/") {
          url = import.meta.env.VITE_APP_API_URL + data.url;
        } else {
          url = data.url;
        }
      }
      // console.log(data);
    }).catch(f=>{
      tag=false;
    });
  }
  return {success:tag,url:url};
}

使用如下

//将上传文件传入
let result = await ApiService.uploadFile(data);
if (data.success) {
  //上传成功,并返回了文件路径
  value.value = data.url;
    
} else {
  swalMessage.error("上传失败")
}

后端代码

public virtual ActionResult Plupload(PluploadInputDto input)
{
    AjaxResponse ajaxResponse = new AjaxResponse(false);
    //过滤文件名的异常字符,只能剩余中文字母及数字,防止恶意攻击()
    input.name = StringHelper.SafeSearchStrFileName(input.name, "_");

    //根据文件后缀判断是否在允许上传格式中
    if (!allowFileExt.Contains(Path.GetExtension(input.name).ToLower().Replace(".", string.Empty))) { return Json(ajaxResponse); }
    //每个用户一个文件夹
    string uid = HttpContext.User.Identity.Name.ToUpper().ToMd5();
    string returnPath = "";

    //再次处理文件名
    input.name = StringHelper.SafeSearchStrFileName(Path.GetFileNameWithoutExtension(input.name), "_") + Path.GetExtension(input.name);

    if (input.file == null)
    {
        return Json(ajaxResponse);
    }
    
    string basePath = "/assets/userfiles/{0}/temp/".FormatWith(uid);
    string path = _env.WebRootPath +basePath;
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }

    if (input.chunks == 1)
    {
        //单个上传
        //重新生成文件名,防止文件重复
        input.name = Guid.NewGuid().ToString("n") + input.name;
        string fileNamePath = path + input.name;
        using (FileStream stream = new FileStream(fileNamePath, FileMode.Create))
        {
            input.file.CopyTo(stream);
        }

        ajaxResponse.Success = true;
        ajaxResponse.Result = new { url= Url.Content("~"+basePath+input.name)};
        return Json(ajaxResponse);
    }
    else
    {
        //多个分片上传
        var key = Guid.NewGuid().ToString("n");
        if (input.chunk==0)
        {
            input.name = key + input.name;
            string fileNamePath = path + input.name;
            using (FileStream stream = new FileStream(fileNamePath, FileMode.Create))
            {
                input.file.CopyTo(stream);
            }
            ajaxResponse.Success = true;
            ajaxResponse.Result = new { key=key };
            return Json(ajaxResponse);
        }
        else
        {
            //第一次以后的上传
            if (!input.key.IsGuid())
            {
                return Json(ajaxResponse);
            }

            key=input.key;
            input.name = input.name + ".bak";
            input.name = input.key + input.name;
            string fileNamePath = path + input.name;
            if (!System.IO.File.Exists(fileNamePath))
            {
                return Json(ajaxResponse);
            }
            using (FileStream stream = new FileStream(fileNamePath, FileMode.Append))
            {
                input.file.CopyTo(stream);
            }

            if (input.chunk == (input.chunks-1))
            {
                //最后的上传成功
                var name2=input.name.Substring(0, input.name.Length - 4);
                System.IO.File.Move(fileNamePath,path + name2);
                
                ajaxResponse.Success = true;
                ajaxResponse.Result = new { url= Url.Content("~"+basePath+name2)};
                return Json(ajaxResponse);
            }
            else
            {
                ajaxResponse.Success = true;
                ajaxResponse.Result = new { key=key };
                return Json(ajaxResponse);
            }
        }
    }
}
posted @ 2024-05-19 21:07  静坐仰望星空  阅读(62)  评论(0编辑  收藏  举报