uni-app ios使用uploadFile上传文件时,服务器返回非200状态码,success回调中无法获取服务器返回的数据
uni-app ios使用uploadFile上传文件时,服务器返回非200状态码,success回调中无法获取服务器返回的数据
信息类别 | 详情 |
---|---|
产品分类 | uniapp/App |
PC开发环境操作系统 | Windows |
PC开发环境操作系统版本号 | win10 |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 4.36 |
手机系统 | iOS |
手机系统版本号 | iOS 18 |
手机厂商 | 苹果 |
手机机型 | iphone 11 |
页面类型 | vue |
vue版本 | vue2 |
打包方式 | 云端 |
项目创建方式 | HBuilderX |
示例代码:
uni.uploadFile({
url: fyURL,
method: 'post',
filePath: data.path,
name: 'image',
success (res) {
console.log(res) // res.data为空
let data = res?.data
try{
data = JSON.parse(data)
}catch(e){
data = null
}
resolve(data || {
code: 400,
msg: '识别文字失败'
})
},
fail (e) {
resolve('服务异常,识别失败')
}
})
操作步骤:
服务器返回401status,并携带响应数据。 ios的uploadFile的success回调获取不到服务器返回的响应数据
预期结果:
{
"data": "{\"code\":4001,\"msg\":\"试用次数已用完,请登录后继续使用哦~\"}",
"statusCode": 401,
"errMsg": "uploadFile:ok"
}
实际结果:
{
"data": "",
"statusCode": 401,
"errMsg": "uploadFile:ok"
}
bug描述:
ios使用uploadFile上传文件,服务器返回401状态码,success回调中获取不到服务器返回的数据
请求响应内容 Response如下:
HTTP/1.1 401 Unauthorized
Server: openresty
Date: Mon, 02 Dec 2024 09:17:01 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 74
Connection: keep-alive
Access-Control-Allow-Credentials: ture
Access-Control-Allow-Headers:
Access-Control-Allow-Methods: GET, HEAD, POST, PATCH, PUT, DELETE
Access-Control-Allow-Origin:
Access-Control-Allow-Private-Network: ture
Access-Control-Expose-Headers: Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Anonymous-Id
Access-Control-Max-Age: 86400
Anonymous-Id: f16bed9bd7920cc5b1cb2147fe5bbda1
Error: 试用次数已用完,请登录后继续使用哦~
Traceparent: 00-6acb6fe1791b03afbb211f56de55a698-6513d209430cd924-00
Vary: Origin
{"code":4001,"msg":"试用次数已用完,请登录后继续使用哦~"}
-------------------------------------------------------------------分割线-------------------------------------------------------------------
以上是抓包的返回,在ios真机中的 uni.uploadFile 的 success 回调中返回的是以下数据,data为空
{
"data": "",
"statusCode": 401,
"errMsg": "uploadFile:ok"
}
-------------------------------------------------------------------分割线-------------------------------------------------------------------
在安卓真机中的 uni.uploadFile 的 success 回调中返回的是以下数据,data是服务器返回的数据
{
"data": "{\"code\":4001,\"msg\":\"试用次数已用完,请登录后继续使用哦~\"}",
"statusCode": 401,
"errMsg": "uploadFile:ok"
}
ios 模拟器是否正常,其他同事的 ios 真机是否正常,都有问题还是 ios18 有问题?
没有在模拟器试过,目前只在真机测试
我这也是同样的问题,求跟进!!
在uni-app中,使用uploadFile
方法进行文件上传时,如果服务器返回非200状态码,默认情况下,success
回调中确实无法直接获取到服务器返回的数据。这是因为uni-app
的uploadFile
方法设计上是将HTTP状态码200-299视为成功,而其他状态码会被视为失败,触发fail
回调。
为了处理非200状态码并获取服务器返回的数据,你可以通过以下几种方式实现:
方法一:在服务器端调整状态码
最直接的方法是调整服务器端逻辑,确保在文件上传成功后总是返回200状态码,即使上传的文件有问题,也可以通过返回的数据体中的状态码或错误信息来告知客户端。
方法二:使用原生请求(如uni.request)模拟文件上传
如果无法改变服务器行为,你可以考虑使用uni.request
方法,通过FormData对象来模拟文件上传,这样可以自定义处理HTTP响应。
uni.chooseImage({
count: 1,
success: function (chooseImageRes) {
const tempFilePaths = chooseImageRes.tempFilePaths;
uni.getFileSystemManager().readFile({
filePath: tempFilePaths[0],
encoding: 'base64',
success: function (res) {
const data = 'file=' + encodeURIComponent(res.data);
uni.request({
url: 'https://your-server-url/upload',
method: 'POST',
header: {
'Content-Type': 'multipart/form-data'
},
data: data,
success: function (uploadFileRes) {
console.log('Server response:', uploadFileRes.data);
},
fail: function (error) {
console.error('Upload failed:', error);
}
});
},
fail: function (error) {
console.error('Read file failed:', error);
}
});
}
});
注意:上述代码示例使用了base64
编码来发送文件数据,这通常适用于小文件。对于大文件,应考虑分片上传或使用更高效的二进制数据传输方式。
方法三:捕获fail
回调并解析响应数据
虽然fail
回调通常不包含详细的响应数据,但在某些uni-app版本或特定平台上,你可能会发现fail
回调的errMsg
对象中包含了响应数据(这取决于uni-app的实现和平台支持)。然而,这不是一个可靠的方法,因为不同版本和平台的行为可能不一致。
综上所述,推荐使用方法二,即使用uni.request
结合FormData来模拟文件上传,这样可以更灵活地处理服务器的响应。