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

React+Axios调用Node接口报CORS跨域及504错误问题求助

问题背景

我目前处于编程学习阶段,如有疏漏敬请谅解,也十分感谢大家提供的建议。
后端API部署在域名api-myapp.com上,当前在本地localhost环境开发前端,尝试使用axios提交仅登录用户可发送的表单时,请求等待时间很长,最终返回两类错误:

  • No 'Access-Control-Allow-Origin' header is present on the requested resource
  • net::ERR_FAILED 504
    已尝试网上公开的多种通用解决方案均未生效,相关代码如下。
相关代码

前端代码

提交学生信息接口调用逻辑

try {
  const response = await axios.post('/alunos/', {
    nome,sobrenome,idade,sangue,varinha,patrono,house,sala,
  });
  toast.success('Cadastrado com sucesso');
  console.log(response);
} catch (e) {
  console.log(e);
  const errors = get(e, 'response.data.errors', []);
  errors.map((error) => toast.error(error));
}

登录逻辑代码

try {
  const response = yield call(axios.post, '/tokens', payload);
  yield put(actions.loginSuccess({ ...response.data }));
  axios.defaults.headers.Authorization = `Bearer ${response.data.token}`;
  toast.success('Login realizado com sucesso!');
  payload.navigate('/dashboard');
}

后端Express服务代码

class App {
  constructor() {
    this.app = express();
    this.middlewares();
    this.routes();
  }

  middlewares() {
    this.app.use(cors({ origin: '*' }));
    this.app.use(helmet({ crossOriginResourcePolicy: false }));
    this.app.use(express.urlencoded({ extended: true }));
    this.app.use(express.json());
    this.app.use('/images/', express.static(resolve(__dirname, '..', 'uploads', 'images')));
  }

  routes() {
    this.app.use('/', homeRoutes);
    this.app.use('/prof', profRoutes);
    this.app.use('/tokens', tokenRoutes);
    this.app.use('/alunos', alunoRoutes);
    this.app.use('/casas', casaRoutes);
    this.app.use('/provas', provaRoutes);
    this.app.use('/materias', materiaRoutes);
    this.app.use('/salas', salaRoutes);
    this.app.use('/fotosAlunos', fotoAlunoRoutes);
    this.app.use('/fotosProf', fotoProfRoutes);
  }
}
问题定位思路
  1. 先区分错误优先级:504网关超时是核心错误,CORS报错是次生问题。只要请求没有拿到后端正常返回的响应,不管是超时、被拦截、路由没匹配上,返回的响应都不会带CORS头,浏览器就会抛跨域错误,不要一开始就死磕CORS配置。
  2. 排查请求链路是否通畅:先确认POST请求有没有真的走到Express服务。如果服务前面套了Nginx、云负载均衡、API网关、WAF,先查代理层有没有把/alunos/路径的请求正确转发到Express端口,有没有被安全规则拦截带Authorization头的POST请求,代理超时阈值是不是设置过短。
  3. 排查路由匹配问题:前端提交请求的路径是/alunos/(末尾带斜杠),后端挂载路由的路径是/alunos(末尾无斜杠),如果路由层没做斜杠兼容,会直接匹配不到路由,请求挂起直到超时。
  4. 排查非简单请求的预检处理:带Authorization头的请求属于非简单请求,浏览器会先发OPTIONS预检请求,当前的CORS配置虽然写了通配符,但如果cors中间件没正确覆盖OPTIONS方法,或者没有放行Authorization头,预检请求失败也会导致正式请求发不出去。
  5. 排查业务逻辑是否挂起:因为这个接口是登录后才能访问的,重点查alunoRoutes里的鉴权中间件有没有逻辑漏洞,比如漏写next()、校验失败分支没返回响应、出现死循环,都会导致请求一直不返回,触发超时。
  6. 排查前端基础配置:代码里的请求都是相对路径,要确认axios有没有配置正确的baseURL指向https://api-myapp.com,如果没配,请求会默认发到前端本地服务的地址,本地服务没配代理转发也会出问题。
可行修复方案

按以下顺序排查修复,不要跳步:

  • 链路验证:在alunoRoutes的最外层加一行打印日志,发一次表单请求,看后端能不能收到请求。如果收不到,直接去查部署层的代理转发、WAF、超时配置,不要改业务代码。
  • 修正CORS配置,明确放行规则,兼容预检请求:
// 替换原来的cors配置,origin填你前端本地实际运行的地址,比如vite默认是5173,react脚手架默认是3000
this.app.use(cors({
  origin: ['http://localhost:3000', 'http://localhost:5173'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
}));
// 全局放行OPTIONS预检请求,直接返回200
this.app.options('*', cors());
  • 统一路径斜杠规则,避免路由匹配失败。要么把前端请求路径改成/alunos去掉末尾斜杠,要么在后端路由挂载前加统一处理中间件:
// 放在cors、json解析中间件之后,路由挂载之前
this.app.use((req, res, next) => {
  if (req.path.length > 1 && req.path.endsWith('/')) {
    const queryPart = req.url.slice(req.path.length);
    // 307重定向保证POST请求的方法和请求体不会丢失
    res.redirect(307, req.path.slice(0, -1) + queryPart);
  } else {
    next();
  }
});
  • 排查所有路由和中间件的响应逻辑:尤其是鉴权相关的中间件,确保每一个逻辑分支要么调用next()走到下一个环节,要么直接返回HTTP响应,绝对不能出现既不next也不返回响应的分支,否则请求会一直挂起。
  • 确认前端axios配置:在axios初始化的地方加上baseURL: 'https://api-myapp.com',确保相对路径的请求会正确发到后端域名,而不是前端本地服务。

排查时优先看后端服务的实时日志,只要日志里能收到请求、且路由逻辑走完有响应记录,再去核对CORS头是否正确,90%的类似场景下CORS报错都不是根因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:45:34