uni-app 真机调试:手动代理环境下访问内网 API 的解决方案
背景
使用 uni-app 开发了一款移动应用,需要调用部署在公司内网的 API 服务,地址为http://10.13.5.195:8005。
公司对所有测试手机统一管理,要求 WiFi 必须设置手动代理:
| 配置项 | 值 |
|---|---|
| 代理服务器 | 172.16.95.16 |
| 端口 | 80 |
| 不使用的网址 | *.xxxx.com.cn |
设置手动代理后,App 所有网络请求都会经过代理服务器转发。由于代理服务器无法访问10.13.5.195这个内网地址,导致 API 请求全部失败。
尝试过但不可行的方案
| 方案 | 结果 |
|---|---|
手机代理排除列表加10.* | 公司不允许修改,且需要逐一配置大量手机 |
| Android Studio 原生插件(Proxy.NO_PROXY) | 电脑无法访问外网,缺少 uni-app SDK 的 AAR 文件(uniapp-v8-release.aar),无法编译 |
UTS 插件继承ProxySelector | UTS 对 Java 抽象类的继承存在类型兼容问题,反复报错 |
最终方案
使用 UTS 插件调用java.lang.System.setProperty("http.nonProxyHosts", ...)设置 Java 代理排除规则,让内网 IP 段的请求自动绕过系统代理。
方案原理
Android 底层使用 Java 的网络栈,http.nonProxyHosts是 Java 标准的代理排除属性。设置后,匹配该规则的地址将直接连接,不经过系统代理:
设置前:App 请求 → 系统代理(172.16.95.16) → 无法到达 10.13.5.195 → 报错 设置后:App 请求 → 检查 nonProxyHosts → 匹配 10.* → 直连 10.13.5.195 → 成功对于uni.request()的调用方式完全透明,现有代码一行都不用改。
环境信息
| 项目 | 版本 |
|---|---|
| HBuilderX | 5.07 |
| uni-app 项目类型 | Vue 3(app-vue) |
| 测试手机 | Android |
操作步骤
一、创建 UTS 插件
在 uni-app 项目上右键→新建 uni_modules 目录→ 输入插件 ID(格式要求:作者ID-插件名称,例如hjl-directhttp)→ 选择分类为UTS插件-API插件→ 点击创建。
HBuilderX 会自动生成以下目录结构:
uni_modules/ └── hjl-directhttp/ ├── utssdk/ │ ├── app-android/ │ │ └── index.uts ← Android 平台实现(核心) │ ├── app-harmony/ ← 鸿蒙平台(本次不用) │ ├── app-iOS/ ← iOS 平台(本次不用) │ ├── interface.uts ← 接口声明 │ └── unierror.uts ← 错误处理(本次不用) ├── package.json ← 插件配置 ├── changelog.md └── readme.md二、编辑 interface.uts
声明插件对外暴露的函数接口。
文件路径:uni_modules/hjl-directhttp/utssdk/interface.uts
exportfunctionsetupProxyBypass():UTSJSONObject三、编辑 index.uts(核心)
这是插件的核心实现,调用 Java 系统属性设置代理排除规则。
文件路径:uni_modules/hjl-directhttp/utssdk/app-android/index.uts
/** * DirectHttp - 绕过系统代理访问内网 API * * 原理:通过设置 Java 系统属性 http.nonProxyHosts, * 让匹配内网 IP 段的请求自动绕过代理直连。 * * 覆盖的内网 IP 段: * 10.x.x.x * 172.16.x.x ~ 172.31.x.x * 192.168.x.x * 127.0.0.1 / localhost */exportfunctionsetupProxyBypass():UTSJSONObject{try{java.lang.System.setProperty("http.nonProxyHosts","10.*|192.168.*|172.16.*|172.17.*|172.18.*|172.19.*|172.20.*|172.21.*|172.22.*|172.23.*|172.24.*|172.25.*|172.26.*|172.27.*|172.28.*|172.29.*|172.30.*|172.31.*|127.0.0.1|localhost")console.log("DirectHttp: 代理排除规则设置成功")constr={}asUTSJSONObject r["success"]=truer["message"]="配置成功"returnr}catch(e){console.error("DirectHttp: 配置失败 - "+e.message)constr={}asUTSJSONObject r["success"]=falser["error"]=e.messagereturnr}}四、修改 App.vue
在onLaunch中调用插件初始化函数,App 启动时执行一次即可。
文件路径:根目录App.vue
<script>// #ifdef APP-PLUSimport{setupProxyBypass}from'@/uni_modules/hjl-directhttp'// #endifexportdefault{onLaunch(){console.log('App Launch')// #ifdef APP-PLUStry{constresult=setupProxyBypass()console.log('代理绕过配置结果:',JSON.stringify(result))}catch(e){console.error('DirectHttp 加载失败:',e)}// #endif// ... 原有的 onLaunch 代码保持不变},onShow(){// 原有代码保持不变},onHide(){// 原有代码保持不变}}</script>五、修改 manifest.json
在源码视图中注册插件。
打开manifest.json→ 点击底部「源码视图」→ 找到app-plus→distribute→ 添加nativePlugins:
{"app-plus":{"distribute":{"nativePlugins":{"hjl-directhttp":{}}}}}六、打包测试
HBuilderX →运行 → 运行到手机或模拟器 → 制作自定义基座
等待云打包完成并安装到手机。
七、验证结果
在 HBuilderX 控制台中查看日志,出现以下内容表示配置成功:
DirectHttp: 代理排除规则设置成功 代理绕过配置结果: {"success":true,"message":"配置成功"}此时访问http://10.13.5.195:8005的 API 请求会自动绕过代理直连,登录等业务功能恢复正常。
项目文件清单
整个方案涉及的文件如下:
项目根目录/ ├── uni_modules/ │ └── hjl-directhttp/ │ ├── utssdk/ │ │ ├── app-android/ │ │ │ └── index.uts ← 核心:设置代理排除规则 │ │ ├── interface.uts ← 接口声明 │ │ └── ... │ └── package.json ← 自动生成,无需修改 ├── App.vue ← 调用插件初始化 └── manifest.json ← 注册插件踩坑记录
1. UTS 插件 ID 格式
创建 uni_modules 目录时,插件 ID 必须包含短横线,格式为作者ID-插件名称,例如hjl-directhttp。直接输入directhttp会提示格式不正确。
2. 继承 Java 抽象类的问题
最初尝试在 UTS 中继承java.net.ProxySelector来实现更灵活的代理控制,但遇到一系列编译问题:
- 抽象类不能直接
new,必须用class extends继承 - 覆盖父类方法必须加
override关键字 - 不能显式声明
override方法的返回类型,需要让编译器自动推断 Collections.singletonList()返回的是 Kotlin 集合类型,无法直接当java.util.List使用ArrayList.size是属性而非方法,不能加括号调用- 循环变量是
Number类型,传给ArrayList.get(Int)需要as Int转换
这些问题说明 UTS 对 Java 原生 API 的调用存在较多类型系统差异,涉及抽象类继承、泛型、集合类型转换等场景时容易踩坑。
3. 最终选择的简洁方案
System.setProperty("http.nonProxyHosts", ...)是一行代码就能解决的问题,完全避免了上述所有类型兼容问题。
适用场景
本方案适用于以下情况:
- 公司要求手机使用手动代理,但部分内网服务需要直连
- 无法修改手机代理排除列表(设备多、不允许修改等)
- 使用 uni-app 开发,且 HBuilderX 版本支持 UTS 插件(5.0+)
如需调整排除的 IP 段,只需修改index.uts中http.nonProxyHosts的值即可。