FormData兼容性踩坑

前端在开发H5应用的时候发现,用FormData的方式提交单个文件在iOS的浙政钉会出现兼容性问题,报错信息大概分为两类:

Required request part 'file' is not present 

the request was rejected because no multipart boundary was found

兼容性测试结果如下:

Chrome

微信

浙政钉

Windows

/

/

Android

/

iOS

/

小伙伴发现iOS端浙政钉的FormData数据结构大概是这样婶儿滴:

{
	appendData:{},
	realFormData:{}
}

然后找到了解决系统兼容性中FormData对象包含appendData和realFormData属性这篇博客,引入了第三方FormData,并且axios传输参数如下处理:

data:formData.realFormData || formData

但是问题依旧,最后翻遍全网,发现一篇《解决axios发送post请求上传文件到后端的问题(multipart/form-data)》文章写的比较靠谱,它是这样说的:

axios在请求发送出去之前会进行一次拦截,自动给请求设置一些参数。浙政钉会出现application/json这个参数就是因为axios设置了post请求的默认请求头,如果没有在config中指定其它请求头的话,就会使用默认的

【解决办法】:axios的config中有一个transformRequest属性,官方的解释是可以在请求发送之前人为干预。属性值是一个数组,里面可以定义一个函数,接收两个参数,分别是data和headers。data就是定义的FormData对象,headers里面则是axios预定义的请求头。有了transformRequest之后,axios就不会自动设置参数了

  // `transformRequest` allows changes to the request data before it is sent to the server
  // This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE'
  // The last function in the array must return a string or an instance of Buffer, ArrayBuffer,
  // FormData or Stream
  // You may modify the headers object.
  transformRequest: [function (data, headers) {
  // Do whatever you want to transform the data

     return data;
  }],

激动人心的时刻,上示例代码!!!

前端

upload(file) {
   return uploadFile({
      url: '/api/files',
      method: 'POST',
      transformRequest: [],
      headers: {
        'Content-Type': 'multipart/form-data',
        Authorization: getToken(),
      },
      data: file,
   });
}

后端

    @PostMapping("/files")
    public String uploadFile(@RequestParam MultipartFile file) throws Exception {
        return uploadSmallFileWithMd5(file);
    }

    /**
     * 获取文件扩展名
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    public String uploadSmallFileWithMd5(MultipartFile multipartFile) throws Exception {
        String extensionName = getExtensionName(multipartFile.getOriginalFilename()).toLowerCase();
        String[] fileNames =
            {"doc", "docx", "xls", "xlsx", "jpg", "jpeg", "bmp", "tiff", "gif", "png", "pdf", "pptx", "dwg", "avi",
                "mov", "mp4", "zip", "rar"};
        if (!Arrays.asList(fileNames).contains(extensionName)) {
            throw new Exception("文件格式无法识别!");
        }
        String filePath;
        String fileName = multipartFile.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
		// 兼容Linux服务器中文乱码问题
        fileName = UUID.randomUUID() + suffixName;
        filePath = "/Users/zhan/Desktop/" + fileName;
        File file = new File(filePath);
        multipartFile.transferTo(file);
        return "SUCCESS";
    }

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值