You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo SDK 49升级后EAS构建Android包fetch请求失败

Expo SDK 49 EAS构建Android包网络请求失败问题解决指南

问题概述

  • Expo Go环境下所有功能正常,但通过eas build -p android构建的Android安装包无法完成登录,报错TypeError: Network request failed
  • 该问题仅在将Expo SDK从46升级到49后出现,此前版本运行正常
  • 已尝试更新所有依赖、移除未满足依赖库、清除yarn/npm缓存、切换包管理器、更换电脑、切换Node.js v16/v18,均未解决
  • 开发与生产环境使用同一HTTP服务端,构建过程无报错,仅登录功能异常

优先排查方向

1. 解决HTTP明文请求限制(最常见原因)

从Expo SDK 48开始,生产构建默认启用Android网络安全配置,阻止所有HTTP明文请求(仅允许HTTPS)。如果你的服务端使用HTTP协议,必须手动配置允许明文流量:

在app.json或app.config.js中添加以下配置:

{
  "expo": {
    "android": {
      "networkSecurityConfig": {
        // 允许指定域名的明文请求
        "domainConfigs": [
          {
            "domain": "你的服务端域名或IP",
            "cleartextTrafficPermitted": true
          }
        ]
        // 如果是测试环境,也可以全局允许明文请求(不建议生产用)
        // "cleartextTrafficPermitted": true
      }
    }
  }
}

2. 修复Metro配置导致的polyfill缺失

你的metro.config.js使用异步函数导出配置,可能导致打包时全局对象(如fetch)的polyfill未被正确加载。修改为同步配置:

const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

// 直接添加mjs扩展名,无需异步函数
config.resolver.sourceExts = [...config.resolver.sourceExts, 'mjs'];

module.exports = config;

3. 手动注入Fetch Polyfill

生产构建中可能丢失fetch的全局polyfill,手动添加whatwg-fetch:

  1. 安装依赖:
yarn add whatwg-fetch
  1. 在项目入口文件AppEntry.js顶部导入:
import 'whatwg-fetch';

4. 同步Babel配置与SDK版本

当前@babel/core版本(7.20.0)与Expo SDK 49不匹配,可能导致polyfill注入失败:

  1. 更新依赖:
yarn add -D @babel/core@^7.22.0
  1. 修改babel.config.js,确保生产环境注入全局polyfill:
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    env: {
      production: {
        plugins: ['react-native-polyfill-globals']
      }
    }
  };
};
  1. 安装所需插件:
yarn add -D react-native-polyfill-globals

5. 验证EAS构建环境变量

确认EAS构建时使用了正确的服务端地址,避免生产环境配置错误:
在eas.json中配置生产环境变量:

{
  "build": {
    "production": {
      "env": {
        "API_URL": "你的生产服务端地址"
      }
    }
  }
}

附用户提供的配置文件

package.json

{
  "name": "my_app_name",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@react-native-async-storage/async-storage": "1.18.2",
    "@react-navigation/bottom-tabs": "^6.5.8",
    "@react-navigation/native": "^6.1.7",
    "@react-navigation/native-stack": "^6.9.13",
    "expo": "^49.0.8",
    "expo-barcode-scanner": "~12.5.3",
    "expo-camera": "~13.4.2",
    "expo-linear-gradient": "~12.3.0",
    "expo-localization": "~14.3.0",
    "expo-secure-store": "~12.3.1",
    "expo-status-bar": "~1.6.0",
    "i18n-js": "^4.3.0",
    "react": "18.2.0",
    "react-native": "0.72.4",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-loading-spinner-overlay": "^3.0.1",
    "react-native-safe-area-context": "4.6.3",
    "react-native-screens": "~3.22.0",
    "react-native-svg": "13.9.0",
    "victory-native": "^36.6.11"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

babel.config.js

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo']
  };
};

metro.config.js

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

// module.exports = getDefaultConfig(__dirname);

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

module.exports = (async () => {
   const {
      resolver: { sourceExts },
   } = config;

   return {
      ...config,
      resolver: {
         ...config.resolver,
         sourceExts: [...sourceExts, 'mjs'],
      },
   };
})();

gradle日志

> Task :react-native-async-storage_async-storage:compileReleaseJavaWithJavac
Note: /home/expo/workingdir/build/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStorageModule.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: /home/expo/workingdir/build/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/AsyncStoragePackage.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:2728:18: warning: the variable "DebuggerInternal" was not declared in function "__shouldPauseOnThrow"
          typeof DebuggerInternal !== 'undefined' &&
                 ^~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:11514:7: warning: the variable "setTimeout" was not declared in function "logCapturedError"
setTimeout(function () {
      ^~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:9474:108: warning: the variable "nativeFabricUIManager" was not declared in function "onChange"
...lInstanceHandle ? (from && nativeFabricUIManager.setIsJSResponder(from.sta...
                              ^~~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:10095:21: warning: the variable "clearTimeout" was not declared in anonymous function " 264#"
    cancelTimeout = clearTimeout;
                    ^~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:13845:
30: warning: the variable "__REACT_DEVTOOLS_GLOBAL_HOOK__" was not declared in anonymous function " 264#"
  if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:15730:5: warning: the variable "setImmediate" was not declared in function "handleResolved"
    setImmediate(function () {
    ^~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:19906:12: warning: the variable "fetch" was not declared in anonymous function " 499#"
    fetch: fetch,
           ^~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:19907:14: warning: the variable "Headers" was not declared in anonymous function " 499#"
    Headers: Headers,
             ^~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:19908:14: warning: the variable "Request" was not declared in anonymous function " 499#"
    Request: Request,
             ^~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:19909:15: warning: the variable "Response" was not declared in anonymous function " 499#"
    Response: Response
              ^~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20066:24: warning: the variable "FileReader" was not declared in function "readBlobAsArrayBuffer"
      var reader = new FileReader();
                       ^~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20117:36: warning: the variable "Blob" was not declared in anonymous function " 510#"
        } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
                                   ^~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20119:40: warning: the variable "FormData" was not declared in anonymous function " 510#"
        } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
                                       ^~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20121:44: warning: the variable "URLSearchParams" was not declared in anonymous function " 510#"
...e if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body...
                                 ^~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20240:26:
warning: the variable "AbortController" was not declared in anonymous function " 516#"
          var ctrl = new AbortController();
                         ^~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:20373:23: warning: the variable "XMLHttpRequest" was not declared in anonymous function " 520#"
var xhr = new XMLHttpRequest();
                      ^~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:19919:71: warning: the variable "self" was not declared in anonymous function " 502#"
...undefined' && globalThis || typeof self !== 'undefined' && self ||
                                      ^~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:24796:27: warning: the variable "performance" was not declared in anonymous function " 711#"
  if ("object" === typeof performance && "function" === typeof performance.no...
                          ^~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:24819:26: warning: the variable "navigator" was not declared in anonymous function " 711#"
  "undefined" !== typeof navigator && undefined !== navigator.scheduling && u...
                         ^~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:24929:37: warning: the variable "MessageChannel" was not declared in anonymous function " 711#"
  };else if ("undefined" !== typeof MessageChannel) {
                                    ^~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:24944:34: warning: the variable "nativeRuntimeScheduler" was not declared in anonymous function " 711#"
... = "undefined" !== typeof nativeRuntimeScheduler ? nativeRuntimeScheduler....
                             ^~~~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:36964:34: warning: the variable "requestAnimationFrame" was not declared in function "start 9#"
...    this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this));
                              ^~~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:90654:9: warning: the property "alignItems" was set multiple times in the object definition.
        alignItems: 'center',
        ^~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:90652:9: note: The first definition was here.
        alignItems: 'center',
        ^~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:106933:13: warning: the property "alignItems" was set multiple times in the object definition.
            alignItems: 'center',
            ^~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:106931:13: note: The first definition was here.
            alignItems: 'center',
            ^~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:106961:13: warning: the property "alignItems" was set multiple times in the object definition.
            alignItems: 'center',
            ^~~~~~~~~~~~~~~~~~~~
/home/expo/workingdir/build/android/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle:106959:13: note: The first definition was here.
            alignItems: 'center',
            ^~~~~~~~~~~~~~~~~~~~
> Task :react-native-svg:compileReleaseJavaWithJavac
Note: /home/expo/workingdir/build/node_modules/react-native-svg/android/src/main/java/com/horcrux/svg/VirtualView.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :expo-modules-core:compileReleaseJavaWithJavac
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :expo-secure-store:bundleLibCompileToJarRelease
Note: /home/expo/workingdir/build/node_modules/expo-secure-store/android/src/main/java/expo/modules/securestore/SecureStoreModule.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

内容的提问来源于stack exchange,提问作者rmarques

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 03:54:50