uni-app h5端直连本地硬件唯一可行路径是websocket,因浏览器禁用原生udp/tcp;app端须用原生插件封装udp/tcp;小程序端无法直连,必须通过公网http中转服务。

uni-app H5 端连本地硬件:WebSocket 是唯一可行路径
uni-app 的 H5 模式运行在浏览器中,无法直接发起 UDP/TCP 原生连接,net.Socket、udp.createSocket 会直接报 ReferenceError 或 Cannot find module。但 WebSocket 协议在浏览器中受原生支持,只要硬件端(如 ESP32、树莓派)启用了 WebSocket Server(非 HTTP),且监听在局域网 IP(如 ws://192.168.1.100:8080),H5 就能直连。
注意三点:
- 硬件服务必须响应
Upgrade: websocket请求,不能只是普通 HTTP 接口 - 浏览器若从 HTTPS 页面(如 ngrok 映射的
https://xxx.ngrok-free.app)发起ws://连接,会被标记为“混合内容”而静默拦截;必须用wss://(即硬件服务也得配 TLS)或确保前端页面本身是 HTTP(仅限调试,微信等平台不接受) - 真机 Safari/Chrome Android 对
ws://192.168.x.x的支持较稳定,但 iOS 微信内置浏览器会主动屏蔽非备案域名的 ws 连接——哪怕地址是内网 IP
App 端直连硬件:必须写原生插件封装 UDP/TCP
uni-app 的 App 编译模式(非小程序/H5)允许通过 uni.requireNativePlugin 调用自定义原生模块,这是访问本地硬件(如串口转 WiFi 模块、打印机、传感器)的唯一合规方式。
典型实现步骤:
- Android 端用
DatagramSocket实现 UDP 广播发现设备,或用Socket建 TCP 长连接;需在AndroidManifest.xml中声明android:usesCleartextTraffic="true"(Android 10+ 强制要求) - iOS 端用
GCDAsyncUdpSocket或NSTCPConnection封装,注意添加后台运行权限(如audio或voip)以维持长连接 - JS 层只调用统一接口,例如:
hardwarePlugin.connect({ host: '192.168.1.100', port: 9876 }),不暴露底层协议细节 - 插件返回的数据应为 ArrayBuffer 或 Base64 字符串,避免 JS 层处理二进制粘包问题
小程序端无法直连:必须加一层 HTTP 中转服务
微信/支付宝/抖音小程序引擎彻底禁止对 192.168.x.x、10.x.x.x 等私有 IP 的任何网络请求,uni.request({ url: 'http://192.168.1.100/api' }) 会直接失败,控制台无错误,errCode 固定为 -1004。
可行替代方案只有两种:
- 让硬件自带轻量 HTTP Server(如 ESP8266 启一个
/control接口),再由你的云函数或自有服务器(部署在公网)作为代理:手机 → 公网中转服务 → 内网硬件 - 中转服务必须主动轮询或监听硬件上报(如 MQTT),不能依赖小程序反向请求硬件;否则仍会因跨域或策略被拒
- 中转接口响应头必须带
Access-Control-Allow-Origin: *(开发期),上线后建议精确到小程序 appId 对应的域名
ngrok/frp 隧道配置关键项:HTTPS + disableHostCheck
即使你把硬件服务映射出去,uni-app 项目本身也必须配合,否则页面打不开或白屏。
两个硬性条件缺一不可:
-
manifest.json的h5.devServer下必须显式加"disableHostCheck": true,否则 ngrok 的随机子域名(如abc123.ngrok-free.app)会被 webpack-dev-server 拒绝,返回 403 - ngrok 启动命令必须带
--scheme https,例如:ngrok http --scheme https 8080;微信只认 HTTPS 回调,HTTP 隧道生成的链接在公众号授权页直接报invalid redirect_uri - 如果还遇到
net::ERR_CERT_COMMON_NAME_INVALID,说明证书域名不匹配,可改用mkcert生成包含localhost和 ngrok 子域名的多域名证书,并在vue.config.js中指定https: { key, cert }
真正容易被忽略的是:每次修改 manifest.json 后必须完整重启项目(npm run dev:h5),热更新不生效;而且免费版 ngrok 子域名每重启就变,微信后台填的「网页授权域名」必须同步更新,否则授权流程卡在重定向环节。











