Expo 开发踩坑记: 配置 Proxy 代理,解决 Web 端 CORS 跨域问题

Expo 开发踩坑记: 配置 Proxy 代理,解决 Web 端 CORS 跨域问题

. 约 3 分钟读完

1 问题背景

在开发 React Native + Expo 应用时,使用 axios 请求后端服务 API 接口,发现 Web 端控制台报错:

 Access to XMLHttpRequest at 'http://192.168.31.5:13378/api/xxx' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

经测试发现:

  • ✅ 安卓/iOS 端请求正常
  • ❌ Web 端跨域请求被浏览器拦截
  • ❗ 后端服务未配置 CORS 响应头且不可修改

2 排查思路

为什么移动端正常?

移动端应用不受浏览器安全策略限制,实际是通过 React Native 的 Network API 发起请求,不存在跨域问题。

Web 端为何失败?

当使用 expo start:web 启动开发服务时,实际运行在浏览器环境中,受同源策略限制。

Expo 支持配置 proxy 吗?

查了 Expo 的文档发现expo-cliapp.json 配置文件中没有关于proxy配置的内容,只找到了web模式下的打包采用了 metro bundler打包和运行。于是找到对应文档,发现可以通过 enhanceMiddleware 添加中间件 http-proxy-middleware 来启用 proxy。

3 解决方案:前端代理

  1. 安装依赖
 npm install http-proxy-middleware -D
  1. 在项目根目录下创建 metro.config.js
 // Learn more https://docs.expo.io/guides/customizing-metro
 const { getDefaultConfig } = require("expo/metro-config");
 const { createProxyMiddleware } = require("http-proxy-middleware");
 ​
 const defaultConfig = getDefaultConfig(__dirname);
 ​
 const config = {
   ...defaultConfig, // 不改变Expo定制的metro配置
   server: {
     ...defaultConfig.server,
     enhanceMiddleware: (middleware) => {
       return (req, res, next) => {
         if (req.url.startsWith("/mock")) { // mock 按你的喜好配置和axios中的拦截一致即可
           return createProxyMiddleware({
             target: "http://192.168.31.5:13378", // 替换为你的后端地址
             changeOrigin: true,
             pathRewrite: { "^/mock": "/" },
           })(req, res, next);
         }
         return middleware(req, res, next);
       };
     },
   },
 };
 ​
 module.exports = config;
  1. 修改axios拦截器请求地址
 axios.interceptors.request.use(async (config) => {
   ...其它业务代码
 ​
   if (__DEV__ && Platform.OS === "web") {
     config.baseURL = "/mock";
   }
 ​
   ...其它业务代码
 ​
   return config;
 });
  1. 重启 expo cli
expo start --web

至此已经能在Web模式下正常访问后端接口。

4 原理说明

  1. 代理路径匹配
    所有以 /mock 开头的请求会被代理中间件捕获
  2. 路径重写
    pathRewrite 将 /mock 前缀替换为后端 API 的基础路径
  3. Header 处理
    changeOrigin: true 会修改请求头中的 Host 字段,确保后端服务能正确接收请求

5 注意事项

  1. 仅开发环境生效
    该配置仅在通过 expo start:web 启动时生效,生产环境部署需另行配置代理
  2. 网络请求可见性
    在 Chrome DevTools 的 Network 面板中,代理请求仍会显示原始路径
  3. 移动端兼容性
    移动端请求需要保持原始地址,可通过环境变量区分运行环境
本篇已被阅读