You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React+Capacitor安卓应用无法通过HTTP访问本地Node.js后端,但手机浏览器可正常访问

React+Capacitor安卓应用无法通过HTTP访问本地Node.js后端,但手机浏览器可正常访问

这种情况我之前开发React+Capacitor应用时也碰到过好几次——明明手机浏览器能顺畅访问本地LAN的后端,可APP里的API请求就是石沉大海。核心问题大多集中在Android WebView的安全策略、Capacitor的导航限制,或者配置没有正确同步上,咱们一步步来解决:

1. 修复Network Security Config的兼容性问题

你已经尝试了network security config,但出现的API等级警告是关键:networkSecurityConfig是Android 7.0(API24)才引入的,而你的minSDK是23,所以API23的设备会直接忽略这个配置,必须同时保留usesCleartextTraffic="true"来兼容低版本。

正确的配置步骤:

  • res/xml目录下创建(如果没有就新建)network_security_config.xml,内容如下:
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
      <!-- 针对API24+设备,允许指定IP的明文流量 -->
      <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">10.0.0.193</domain>
      </domain-config>
      <!-- 全局允许明文流量,兼容API23及以下设备 -->
      <base-config cleartextTrafficPermitted="true" />
    </network-security-config>
    
  • 然后在AndroidManifest.xml<application>标签里同时保留两个配置:
    <application
      ...
      android:usesCleartextTraffic="true"
      android:networkSecurityConfig="@xml/network_security_config"
    >
    
    这样既照顾了API24+的细粒度控制,又保证了API23设备能正常使用明文流量。

2. 配置Capacitor允许导航到本地LAN IP

Capacitor默认会限制WebView导航到非白名单内的域名/IP,必须在Capacitor配置里添加允许规则:

  • 打开项目根目录的capacitor.config.ts(如果是JS就是capacitor.config.js),添加allowNavigation配置:
    import { defineConfig } from '@capacitor/cli';
    
    export default defineConfig({
      appId: 'com.yourapp.id',
      appName: 'YourAppName',
      webDir: 'build',
      android: {
        // 允许WebView与指定IP的后端通信
        allowNavigation: ['10.0.0.193:3000']
      }
    });
    
    这个配置告诉Capacitor的WebView,允许向这个IP端口发起请求,不会拦截导航或XHR请求。

3. 强制WebView允许混合/明文内容

即使开了明文流量权限,Android WebView在某些版本下仍会默认阻止混合内容(比如从HTTPS的WebView加载HTTP资源,纯HTTP场景也可能受影响),我们可以通过自定义Android代码强制开启:

  • 打开android/app/src/main/java/com/yourapp/id/MainActivity.java(路径根据你的appId调整),修改代码如下:
    import android.webkit.WebSettings;
    import com.getcapacitor.BridgeActivity;
    
    public class MainActivity extends BridgeActivity {
      @Override
      public void onStart() {
        super.onStart();
        
        // 获取Capacitor的WebView实例,配置混合内容模式
        if (this.getBridge() != null && this.getBridge().getWebView() != null) {
          WebSettings webSettings = this.getBridge().getWebView().getSettings();
          // 允许所有混合内容,确保HTTP请求能正常发送
          webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
      }
    }
    

4. 确认后端服务器的监听地址

虽然你的手机浏览器能访问,但还是要再确认Node.js服务器是监听在0.0.0.0而不是localhost127.0.0.1——后者只能让本机访问,LAN内其他设备(比如你的手机)是连不上的。检查你的Node启动代码:

// 正确:监听所有网卡,允许LAN设备访问
app.listen(3000, '0.0.0.0', () => {
  console.log('后端运行在 http://0.0.0.0:3000');
});

// 错误:仅本机可访问
// app.listen(3000, 'localhost', () => { ... });

5. 必须执行:同步配置并重新构建

所有配置修改后,一定要同步Capacitor并重新构建项目,不然Android端不会应用新配置:

# 先构建React项目
npm run build
# 同步Capacitor配置到Android工程
npx cap sync android
# 重新安装到手机测试
npx cap run android

6. 排查具体错误(如果还是不行)

如果以上步骤都试了还是没效果,就需要抓具体的错误日志来定位:

  • 在你的React代码里,给API请求加上错误捕获:
    fetch('http://10.0.0.193:3000/api/your-endpoint')
      .then(res => res.json())
      .then(data => console.log('请求成功:', data))
      .catch(err => console.error('请求失败:', err.message, err.stack));
    
  • 用Capacitor的日志工具查看WebView的错误:
    npx cap run android --log
    
    重点看包含net::ERR_开头的错误,比如net::ERR_CLEARTEXT_NOT_PERMITTED(明文流量权限未生效)、net::ERR_CONNECTION_REFUSED(服务器监听地址错误),这些错误能直接告诉你问题根源。

我当时就是卡在Capacitor的allowNavigation配置没加,导致WebView直接拦截了请求,按照这个流程走下来基本就能解决问题啦!

火山引擎 最新活动