uni-app 真机调试:手动代理环境下访问内网 API 的解决方案

uni-app 真机调试:手动代理环境下访问内网 API 的解决方案


背景

使用 uni-app 开发了一款移动应用,需要调用部署在公司内网的 API 服务,地址为 http://10.13.5.195:8005

公司对所有测试手机统一管理,要求 WiFi 必须设置手动代理:

配置项
代理服务器 172.16.95.16
端口 80
不使用的网址 *.mflex.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

typescript 复制代码
export function setupProxyBypass() : UTSJSONObject

三、编辑 index.uts(核心)

这是插件的核心实现,调用 Java 系统属性设置代理排除规则。

文件路径:uni_modules/hjl-directhttp/utssdk/app-android/index.uts

typescript 复制代码
/**
 * 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
 */
export function setupProxyBypass() : 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: 代理排除规则设置成功")
		const r = {} as UTSJSONObject
		r["success"] = true
		r["message"] = "配置成功"
		return r
	} catch (e) {
		console.error("DirectHttp: 配置失败 - " + e.message)
		const r = {} as UTSJSONObject
		r["success"] = false
		r["error"] = e.message
		return r
	}
}

四、修改 App.vue

onLaunch 中调用插件初始化函数,App 启动时执行一次即可。

文件路径:根目录 App.vue

javascript 复制代码
<script>
// #ifdef APP-PLUS
import { setupProxyBypass } from '@/uni_modules/hjl-directhttp'
// #endif

export default {
  onLaunch() {
    console.log('App Launch')

    // #ifdef APP-PLUS
    try {
      const result = setupProxyBypass()
      console.log('代理绕过配置结果:', JSON.stringify(result))
    } catch (e) {
      console.error('DirectHttp 加载失败:', e)
    }
    // #endif

    // ... 原有的 onLaunch 代码保持不变
  },
  onShow() {
    // 原有代码保持不变
  },
  onHide() {
    // 原有代码保持不变
  }
}
</script>

五、修改 manifest.json

在源码视图中注册插件。

打开 manifest.json → 点击底部 「源码视图」 → 找到 app-plusdistribute → 添加 nativePlugins

json 复制代码
{
    "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.utshttp.nonProxyHosts 的值即可。

相关推荐
Hoshizola2 小时前
uniapp与蓝牙设备连接详细步骤
前端·uni-app
优雅格子衫2 小时前
uniapp 拍照相册选取后超级好用的裁剪组件,增加水印完全自定义
开发语言·前端·javascript·uni-app·vue
路光.3 小时前
uniapp中解决webview在app中调用,有过渡空白问题,增加过渡动效
uni-app·vue·app·uniapp
linlinlove24 小时前
前端uniapp、后端thinkphp股票系统开发功能展示、代码披露、HQChart
前端·uni-app·echarts·thinkphp·hqchart·配资·deepseek选股票
2501_915909065 小时前
深入理解HTTPS中间人抓包技术原理与实战指南
网络协议·http·ios·小程序·https·uni-app·iphone
2501_916007471 天前
iOS应用性能优化全面指南:从内存管理到工具使用
android·ios·性能优化·小程序·uni-app·iphone·webview
巴博尔2 天前
UNIAPP中NVUE页面 动画
android·前端·javascript·ios·uni-app
边界条件╝2 天前
uniapp 深度使用
uni-app
路光.2 天前
uniapp小程序/App使用webview打通麦克风权限实现录音功能
小程序·uni-app·app