uni-app H5端uploadFile请求响应没有问题但是会进到fail回调

uni-app H5端uploadFile请求响应没有问题但是会进到fail回调

示例代码:

function dataURLtoFile(dataUrl, fileName) {  
  var arr = dataUrl.split(','),  
    mime = arr[0].match(/:(.*?);/)[1],  
    bstr = atob(arr[1]),  
    n = bstr.length,  
    u8arr = new Uint8Array(n);  
  while (n--) {  
    u8arr[n] = bstr.charCodeAt(n);  
  }  
  return new File([u8arr], fileName, { type: mime });  
}  

uni.uploadFile({  
  url: 'xxx',  
  file: dataURLtoFile(dataurl, 'sign.png'),  
  fileType: 'image',  
  name: 'file',  
  formData: {  
    proj: 'xxx',  
    hashName: 1,  
  },  
})

操作步骤:

  1. 将dataurl转换为文件
  2. 调用uploadFile上传文件

预期结果:

  • 进入success回调,返回接口响应的数据

实际结果:

  • 进入fail回调,返回 {errMsg: 'uploadFile:fail file error'}

bug描述:

h5端调用uploadFile,通过控制台查看请求和响应内容都是没有问题的,但是uploadFile返回{errMsg: 'uploadFile:fail file error'}。文件是通过dataURL转换的File类型,回退到hbuilderX 4.75版本没有问题。


更多关于uni-app H5端uploadFile请求响应没有问题但是会进到fail回调的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

filePath 和 files 不能同时为空,必须设置一个,files 的优先级高于 filePath

更多关于uni-app H5端uploadFile请求响应没有问题但是会进到fail回调的实战教程也可以访问 https://www.itying.com/category-93-b0.html


解决了,参数改为 files: [{ name: ‘file’, file }] 但我还是不能理解为什么在调用上传成功之后才校验参数,4.75版本也没有这个校验,按理说这种基础接口应该很稳定,不应该发生变动

回复 i***@qq.com: 原来这里存在一个bug,files为空仍然会上传文件,新版本修复了

这个问题是HBuilderX 4.75版本之后引入的兼容性问题。主要原因是H5平台对File对象的处理逻辑发生了变化。

问题分析: 在较新版本的uni-app中,H5端对uploadFile的File对象进行了更严格的校验。虽然dataURLtoFile函数生成的File对象在浏览器中有效,但可能缺少某些必要属性或格式不完全符合uni-app的预期。

解决方案:

  1. 使用uni-file-picker组件(推荐) 这是uni-app官方推荐的文件上传方案,能自动处理各种平台的兼容性问题。

  2. 改用Blob对象 将dataURL直接转换为Blob对象进行上传:

function dataURLtoBlob(dataUrl) {
  var arr = dataUrl.split(',');
  var mime = arr[0].match(/:(.*?);/)[1];
  var bstr = atob(arr[1]);
  var n = bstr.length;
  var u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
}

uni.uploadFile({
  url: 'xxx',
  file: dataURLtoBlob(dataurl),
  fileType: 'image',
  name: 'file',
  formData: {
    proj: 'xxx',
    hashName: 1,
  },
})
  1. 回退到Base64直接上传 如果文件不大,可以直接上传Base64字符串:
uni.request({
  url: 'xxx',
  method: 'POST',
  data: {
    file: dataurl,
    proj: 'xxx',
    hashName: 1
  }
})
回到顶部