uni-app H5端应用发起uni.request请求时大部分用户手机正常交互,但部分用户发起请求直接进入fail回调,并提示request fail

uni-app H5端应用发起uni.request请求时大部分用户手机正常交互,但部分用户发起请求直接进入fail回调,并提示request fail

开发环境 版本号 项目创建方式
Windows win 10 64 CLI

示例代码:

uni.request({  
    url:"https://www.xxx.xxx",  
    data:{code:12345},  
    header:{  
        "content-type": "application/json;charset=UTF-8", "Authorization": "UFNyQ3prNkVMUXZySlRLVStJTzl5Y3VNS0N6SXhjUys2dzdhR1hb1Jia"  
    },  
    fail: (err) => {  
        console.log(err);  
    },  
    success: (data) => {  
        console.log(data);  
    }  
})

操作步骤:

  1. 建立一个空uni-app项目
  2. 使用uni.request发起请求,并设置请求头header
  3. H5模式运行到浏览器,使用低版本的ios真机调试
  4. 查看网络请求,发现无法发起请求

预期结果:

发起请求时直接进入fail回调,并提示【request:fail】

实际结果:

发起请求时直接进入fail回调,并提示【request:fail】

bug描述:

【H5端应用】发起【uni.request请求】在大部分用户的手机都能正常交互,但是部分用户发起请求时直接进入fail回调,并提示【request:fail】

出错机型:Redmi Note 8 MIUI 11.0.8 安卓9
出错机型:iphone xs max iso 12.4

【新的发现】只要设置了请求头【header】在低版本ios手机上就无法发起请求


更多关于uni-app H5端应用发起uni.request请求时大部分用户手机正常交互,但部分用户发起请求直接进入fail回调,并提示request fail的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

使用电脑浏览器远程调试就可以看到网络请求具体问题。

更多关于uni-app H5端应用发起uni.request请求时大部分用户手机正常交互,但部分用户发起请求直接进入fail回调,并提示request fail的实战教程也可以访问 https://www.itying.com/category-93-b0.html


浏览器调试是没有问题的,只是在部分低版本的IOS上发现无法发起请求,后台都查不到请求记录

提供一个可复现的demo吧 我这边没有复现,用的iphone xs ios 12.0

已解决,最后发现不是uni-app的问题,应该是IOS兼容性问题,在低版本的IOS上浏览器的安全策略导致的跨域问题

已解决,最后发现不是uni-app的问题,应该是IOS兼容性问题,在低版本的IOS上浏览器的安全策略导致的跨域问题

根据你的描述,问题核心在于部分低版本系统的移动设备(特别是iOS 12)在H5环境下,当uni.request设置了自定义header时,请求会直接失败

这是一个已知的跨域请求(CORS)行为差异问题,主要与浏览器内核版本有关。

问题根因分析

  1. 核心机制:在H5平台,uni.request的本质是浏览器的XMLHttpRequestFetch API。当请求的url与当前页面域名不同(即跨域)时,浏览器会执行严格的CORS预检(Preflight)
  2. 关键差异:你代码中设置的 "content-type": "application/json;charset=UTF-8" 属于 “非简单请求头”。根据CORS规范,浏览器必须先发送一个OPTIONS方法的预检请求,获得服务器明确许可后,才会发送真正的请求。
  3. 低版本系统问题:部分老版本移动设备系统(如iOS 12及更早版本、部分旧版Android WebView)内置的浏览器内核较老,对CORS预检机制的处理可能存在缺陷或兼容性问题。当预检请求未能正确完成或被异常拦截时,主请求就会直接失败,触发fail回调。

解决方案

针对此问题,需要从前端请求配置服务器支持两方面协同解决:

1. 前端修改请求头(推荐首先尝试)content-type 改为 简单请求头 的值,可以避免触发预检请求。简单请求头中关于Content-Type的取值仅限于:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

修改你的代码:

uni.request({  
    url: "https://www.xxx.xxx",  
    data: { code: 12345 },  
    header: {  
        // 将 content-type 改为 application/x-www-form-urlencoded
        "content-type": "application/x-www-form-urlencoded",
        "Authorization": "UFNyQ3prNkVMUXZySlRLVStJTzl5Y3VNS0N6SXhjUys2dzdhR1hb1Jia"  
    },  
    method: 'POST', // 如果后端要求POST,请确保method正确
    success: (res) => { console.log(res.data); },
    fail: (err) => { console.log('请求失败:', err); }
})

注意: 修改后,你的data参数会被以表单编码形式发送。如果你的后端接口强依赖application/json来解析,此方法可能不适用,需同步调整后端或采用方案2。

2. 确保服务器正确配置CORS响应头 这是根本解决之道。你的服务器必须在响应中(尤其是对OPTIONS预检请求的响应)返回正确的CORS头,明确允许来自H5页面域名的请求以及你所使用的自定义头。

服务器需响应的关键头部示例:

Access-Control-Allow-Origin: [你的H5页面域名] 或 *
Access-Control-Allow-Headers: content-type, authorization  // 必须包含你自定义的header字段名
Access-Control-Allow-Methods: GET, POST, OPTIONS           // 根据实际情况设置
回到顶部