Expo应用无法在Android模拟器运行 报自签名证书链错误
根因判断
从报错特征、已排除的变量来看,故障核心是本机全局HTTPS流量劫持导致的TLS校验失败,和项目代码、Expo版本、模拟器配置无关。
常见触发源包括抓包工具(Fiddler/Charles/Whistle)、企业安全管控客户端、全局VPN/代理、广告过滤工具,这类软件会向系统证书链注入自签名根证书,对HTTPS流量做中间人解密。Web端能正常运行是因为浏览器默认信任系统存储的根证书,但Node.js(跑Metro/Expo CLI的运行时)默认只信任内置CA列表,Android模拟器也不会默认信任宿主机上的自签证书,两端同时触发证书校验失败就会报你看到的self signed certificate in certificate chain错误。
之前设置NODE_TLS_REJECT_UNAUTHORIZED=0后出现403,是因为跳过Node侧证书校验后,请求确实打到了中间代理上,但代理本身对本地Expo服务的请求做了拦截鉴权,直接返回403拒绝,不属于证书类问题。
修复方案
按优先级依次操作:
- 先关闭所有可能劫持HTTPS流量的程序
退出所有抓包工具、第三方VPN、企业上网客户端、全局代理/广告过滤软件,检查系统代理设置里是否开了全局HTTP/HTTPS代理,临时关闭后重启VS Code终端、冷启动Android模拟器,重新执行expo start -c清缓存启动项目测试。 - 修正模拟器访问宿主机的地址
Android模拟器的127.0.0.1默认指向模拟器自身,不是运行Metro服务的开发机,宿主机的固定映射地址是10.0.2.2,在Expo Go里手动输入exp://10.0.2.2:19000访问,不要填127.0.0.1。 - 强制代理场景下的证书配置
如果是公司内网要求必须开安全代理无法关闭,不要用NODE_TLS_REJECT_UNAUTHORIZED=0的不安全方案,按以下步骤配置:- 从代理/安全客户端的设置页导出它的自签名根证书,保存为crt/pem格式文件到本地固定路径
- 执行命令
npm config set cafile "你的证书文件绝对路径",给npm配置证书信任 - 新增系统环境变量
NODE_EXTRA_CA_CERTS,值填刚才的证书文件绝对路径,重启终端生效 - 把同一份证书安装到Android模拟器的系统信任证书区,注意Android 7.0以上版本默认不信任用户安装的证书,需要把证书推到
/system/etc/security/cacerts/目录下,或者给调试用的Expo Go配置网络安全规则允许信任用户证书
- 修复403拦截问题
配置完证书后如果还报403,执行以下命令清掉npm侧的代理配置:
再检查系统环境变量里的npm config delete proxy npm config delete https-proxyHTTP_PROXY、HTTPS_PROXY值,新增NO_PROXY环境变量,值为127.0.0.1,localhost,10.0.2.2,192.168.*.*,把本地回环、模拟器地址、局域网地址全部加入代理例外列表,避免本地调试流量被代理拦截。 - 修复Tunnel模式超时
Expo的Tunnel模式底层依赖公网ngrok中继,之前超时就是因为本地代理拦截了ngrok的出站请求,按前面步骤配置好代理例外后即可正常启动。本地调试不需要用Tunnel模式,LOCAL模式配合adb reverse的稳定性最高。
验证流程
所有配置改完后,执行expo start -c强制清除Metro缓存,不要复用之前的缓存进程,模拟器冷启动后打开Expo Go,手动输入exp://10.0.2.2:19000即可正常加载项目。
内容的提问来源于stack exchange,提问作者server_unknown
相关产品推荐
相关产品推荐

