跨平台应用开发进阶(三十六) :uniapp使用uni.request请求报错{“errMsg“:“request:fail abort statusCode:

一、问题呈现

在uniapp中,使用uni.request()向服务端接口发起请求后,返回值为:{"errMsg":"request:fail abort statusCode:-1"},因此,导致了后面的业务代码报错。

通过检查uni.request()根据服务端接口需要的配置(如:url、data、header、method等)都没有问题。

二、问题分析

2.1 手机没有连网

在以上前提下还出现这种问题,最有可能的原因:手机没有连网,或者看着连上了网但实际网络不可用,可以在手机浏览器中随便输入点文字搜一下测试看看,能不能搜到新内容。

仔细查看,这个{"errMsg":"request:fail abort statusCode:-1 未能找到使用指定主机名的服务器。(-1003)"} 返回值,其实并不是服务端返回来的,因为请求都完全没有到服务端。

2.2 https ssl证书解析(未得到验证)

通过对比前后版本差异,发现前期后台请求方式为http:IP形式,当前后台请求方式为https:域名形式。通过http:域名形式检测,未发现以上现象。排除法怀疑问题出在ssl证书验证阶段。

但是andriod不会出现以上问题,只有ios才会出现以上问题。难道android与ios在校验证书方面存在差异?

通过抓包工具Stream分析发现,在出现网路连接问题时抓包信息如下:

抓包详情信息如下:

2.3 data序列化错误

从网上看到如下解释,经过实践,发现问题解决了。

官方文档上说uni.request在content-type:application/json时会尝试对data进行序列化。手动将原本是json的数据转成字符串传进去就可以了,希望官方可以对这一块进行优化吧。

2.4 TCP握手超时失败

通过WhireShark捕获网络层数据,发现TCP握手超时。

并在dmz区的服务器上捕获 netstat packets rejects in established connections because of timestamp 有这个错误。

通过系统参数优化可解决TCP握手超时问题。

在入口服务器打开编辑文件/etc/sysctl.conf,加入以下内容:

java 复制代码
net.ipv4.tcp_tw_reuse=0
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_fin_timeout=10
net.ipv4.ip_local_port_range=1024 65535
net.core.somaxconn=65535
vm.drop_caches=1
vm.swappiness=0
fs.file-max=10485760

然后执行 /sbin/sysctl -p 让参数生效。

三、解决办法

3.1 网络检测

针对手机没有连网的场景,在执行uni.request()向服务端请求前,使用uni.getNetworkType()和uni.onNetworkStatusChange()对网络进行监听,如果监听到当前设备是处于无网络的状态时,就不执行uni.request()请求,而是弹出一个弹框或者消息提示,提醒用户:"当前设备断网了,请检查网络后重试"。

uni. onNetworkStatusChange 触发时机 :在网络切换的时候执行,切换2G,3G,WiFi的时候会执行。 应用时机 :一般都会放在 onShow里面,实时监听网络的切换。当应用关闭后台的时候在 onHide 生命周期函数中执行 uni.offNetworkStatusChange()关闭监听网络。

uni.getNetworkType 触发时机 :在页面初始化的时候,或者是在方法执行的时候执行。 应用时机 :可以再onShow 、onLoad这样的生命周期里面来执行,也可以在点击事件中添加执行,属于即用即取的。

3.2 请求封装

在使用uni.request进行网络请求时,对入参data进行JSON.stringfy()序列化操作。

javascript 复制代码
return new Promise((resolve, reject) => {
	uni.request({
		url: curUrl,
		method: method || "POST",
		header: {
			'Content-Type': 'application/json',
			'Authorization': 'Basic'
		},
		// header: headerForm,
		data: JSON.stringfy(data) || {},
		success(res) {
			setToken(res.data)
			resolve(res.data)
			console.log('The request url(' + curUrl + ')  success return info is: ', res.data)
		},
		fail(err) {
			reject(err)
			console.log('The request url(' + curUrl + ')  fail return info is: ', err)
		},
		complete() {
			// uni.hideLoading()
		}
	})
}).catch(err => {
	handleErr(err)
})

官方文档中关于data 数据说明信息如下:

最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:

  • 对于 GET 方法,会将数据转换为 query string。例如 { name: 'name', age: 18 } 转换后的结果是 name=name&age=18。
  • 对于 POST 方法且 header['content-type'] 为 application/json 的数据,会进行 JSON 序列化。
  • 对于 POST 方法且 header['content-type'] 为 application/x-www-form-urlencoded 的数据,会将数据转换为 query string。

四、拓展阅读

相关推荐
陈随易6 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
福兮说7 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
传人once9 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.469 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
库拉镜像AI牛牛10 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别
律宏阔10 小时前
Flutter 列表图片内存优化:CachedNetworkImage 与 ClipRRect 的取舍
前端·flutter
行者全栈架构师10 小时前
【鸿蒙心迹】相册文搜图工程化落地:HarmonyOS 7.0 端侧 AI 检索全链路实战与 5 个踩坑解法
前端
律宏阔11 小时前
Dart 3 Record:解决 Future.wait 异构返回值的类型问题
前端·flutter
Seraphina3611 小时前
DVWA(XSS Reflected/Stored High,CSRF Low)
前端·xss·csrf
默_笙12 小时前
🍔 中间件不只是打日志:四个钩子、一次短路,和自带的工具
前端·javascript