Cordova打包安卓App无法连接公网Node.js Socket.io服务问题求助
桌面浏览器可正常连接但安卓端无响应、无报错,核心原因是安卓系统的网络限制规则:安卓9.0(API 级别28)及以上版本默认全局禁止HTTP明文流量请求,你当前Socket连接用的是http://MYSERVER:3456的未加密地址,请求会被系统网络层直接拦截,这类拦截不会触发WebView内的JS报错,所以控制台看不到错误信息,服务端也收不到连接请求。
除此之外你现有配置还有两处小问题会影响功能运行:一是Cordova安卓平台默认没配置明文流量放行规则,二是前端DOM选择器书写错误,就算连接成功也无法正常渲染消息。
- 配置网络权限
打开项目根目录的config.xml,在<widget>标签内添加安卓联网权限配置:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- 放开明文流量限制
在config.xml内添加安卓平台专属配置,允许应用发起HTTP明文请求:
<platform name="android"> <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application"> <application android:usesCleartextTraffic="true" /> </edit-config> </platform>
如果你使用的Cordova安卓版本低于9.0,需要手动创建网络安全配置:在项目的resources/android/xml/目录下新建network_security_config.xml,写入以下内容:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
再在AndroidManifest.xml的<application>标签中添加属性android:networkSecurityConfig="@xml/network_security_config"即可。
对齐Socket.IO版本
确认服务端安装的socket.io包版本和前端引入的4.5.1版本一致,2.x版本的服务端和4.x版本的客户端存在协议不兼容问题,会导致连接静默失败,直接把服务端的socket.io升级到4.x最新版即可。补全连接监听、修正前端代码
修改前端Socket初始化逻辑,显式指定传输方式、添加错误监听方便排查问题,同时修正错误的DOM选择器:
$(function(){ // 显式指定传输方式,添加连接配置 var socket = io.connect('http://MYSERVER:3456', { transports: ['websocket', 'polling'] }); // 添加连接错误、断开监听 socket.on('connect_error', (err) => { console.log("连接失败:", err.message); }); socket.on('disconnect', (reason) => { console.log("连接断开:", reason); }); $("form").submit(function (e) { e.preventDefault(); socket.emit("message", $("#messageContent").val()); $("#messageContent").val(""); return false; }) socket.on('message', function(msg) { console.log("收到消息"); // 修正选择器,如果你用的是id选择器要加#,class选择器要加. $("#MessageContainer").append($("<div class='MessageBox'>").text(msg)); }) })
所有配置修改完成后,先执行cordova clean android清空之前的构建缓存,再重新构建应用安装到安卓设备即可正常连接。
如果后续正式上线,建议把服务端升级为HTTPS协议,不需要放开明文流量限制,安全性更高。
内容的提问来源于stack exchange,提问作者serol

