uni-app ios使用uploadFile上传文件时,服务器返回非200状态码,success回调中无法获取服务器返回的数据

发布于 1周前 作者 zlyuanteng 来自 Uni-App

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"
}  

4 回复

ios 模拟器是否正常,其他同事的 ios 真机是否正常,都有问题还是 ios18 有问题?


没有在模拟器试过,目前只在真机测试

我这也是同样的问题,求跟进!!

在uni-app中,使用uploadFile方法进行文件上传时,如果服务器返回非200状态码,默认情况下,success回调中确实无法直接获取到服务器返回的数据。这是因为uni-appuploadFile方法设计上是将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来模拟文件上传,这样可以更灵活地处理服务器的响应。

回到顶部