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

React中window.location.href失效,Node支付接口重定向遇CORS问题

支付功能前端无法跳转:CORS跨域错误导致重定向失败

我用Node做后端、React做前端开发支付功能,后端支付路由能正常生成支付链接并重定向,但前端浏览器没有实际跳转,控制台报出CORS相关错误。

后端支付路由代码

router.post("/", async (req, res, next) => {
  try {
    const token = await firstStep();
    const order = await secondStep(token);
    const paymentToken = await thirdStep(order, token);

    const redirectUrl = `https://accept.paymob.com/api/acceptance/iframes/796922?payment_token=${paymentToken}`;
    res.redirect(redirectUrl);

  } catch (error) {
    next(createError(500, error.message));
  }
});

前端调用代码

const handlePayment = async () => {
  dispatch(setOrderCourse(course));
  try {
    const res = await newRequest.post("payments");
    window.location.href = res.data;
  } catch (err) {
    // console.log(err);
  }
};

浏览器报错信息

从源'http://localhost:3000'访问XMLHttpRequest地址'https://accept.paymob.com/api/acceptance/iframes/796922?payment_token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SjFjMlZ5WDJsa0lqb3hOalV5TlRneExDSmhiVzkxYm5SZlkyVnVkSE1pT2pFd01Dd2lZM1Z5Y21WdVkza2lPaUpGUjFBaUxDSnBiblJsWjNKaGRHbHZibDlwWkNJNk5ETXdPREk1TVN3aWIzSmtaWEpmYVdRaU9qRTNNRGd4TkRNMU5pd2lZbWxzYkdsdVoxOWtZWFJoSWpwN0ltWnBjbk4wWDI1aGJXVWlPaUpEYkdsbVptOXlaQ0lzSW14aGMzUmZibUZ0WlNJNklrNXBZMjlzWVhNaUxDSnpkSEpsWlhRaU9pSkZkR2hoYmlCTVlXNWtJaXdpWW5WcGJHUnBibWNpT2lJNE1ESTRJaXdpWm14dmIzSWlPaUkwTWlJc0ltRndZWEowYldWdWRDSTZJamd3TXlJc0ltTnBkSGtpT2lKS1lYTnJiMnh6YTJsaWRYSm5hQ0lzSW5OMFlYUmxJam9pVlhSaGFDSXNJbU52ZFc1MGNua2lPaUpEVWlJc0ltVnRZV2xzSWpvaVkyeGhkV1JsZEhSbE1EbEFaWGhoTG1OdmJTSXNJbkJvYjI1bFgyNTFiV0psY2lJNklpczROaWc0S1RreE16VXlNVEEwT0RjaUxDSndiM04wWVd4ZlkyOWtaU0k2SWpBeE9EazRJaXdpWlhoMGNtRmZaR1Z6WTNKcGNIUnBiMjRpT2lKT1FTSjlMQ0pzYjJOclgyOXlaR1Z5WDNkb1pXNWZjR0ZwWkNJNlptRnNjMlVzSW1WNGRISmhJanA3ZlN3aWMybHVaMnhsWDNCaGVXMWxiblJmWVhSMFpXMXdkQ0k2Wm1Gc2MyVXNJbVY0Y0NJNk1UY3dNalF5TWpFME1Dd2ljRzFyWDJsd0lqb2lNVFUyTGpJd055NDFOaTR4TURBaWZRLmNHVWgxVGJPMThYcm1vREtJcjZpbmc5WWg2NUk4WEYwNTBIdi1POWJ0OHpWNDFGY1Nic3VKZzhvb21ESk5qSEFmZUlWbWpodkF5bTdkYWtBYmc4cUVn'(从'http://localhost:8800/api/payments'重定向)已被CORS策略阻止:当请求的凭据模式为'include'时,响应中的'Access-Control-Allow-Origin'标头值不能为通配符'*'。XMLHttpRequest发起的请求的凭据模式由withCredentials属性控制。


问题原因

后端直接重定向到第三方支付链接,导致前端Ajax请求跟着重定向到第三方域名,但第三方支付平台的CORS配置不允许你的前端域名(且请求带凭证),浏览器因此拦截了请求,前端拿不到响应也就无法执行跳转逻辑。

修复方案

方案1:后端返回支付链接,前端自行跳转

修改后端路由,取消直接重定向,把生成的支付链接作为响应返回给前端:

router.post("/", async (req, res, next) => {
  try {
    const token = await firstStep();
    const order = await secondStep(token);
    const paymentToken = await thirdStep(order, token);

    const redirectUrl = `https://accept.paymob.com/api/acceptance/iframes/796922?payment_token=${paymentToken}`;
    // 替换重定向为返回链接
    res.status(200).json(redirectUrl);

  } catch (error) {
    next(createError(500, error.message));
  }
});

前端代码无需修改,原本的window.location.href = res.data逻辑可以直接使用返回的链接完成跳转。

方案2:前端直接发起页面跳转(跳过Ajax)

如果不需要在跳转前处理后端返回的额外数据,可以直接让前端通过表单提交跳转到后端支付路由,绕过Ajax的CORS限制:

const handlePayment = () => {
  dispatch(setOrderCourse(course));
  // 用表单提交模拟POST请求跳转
  const form = document.createElement('form');
  form.method = 'POST';
  form.action = '/api/payments';
  document.body.appendChild(form);
  form.submit();
};

这种方式是浏览器原生的页面跳转请求,不会触发XMLHttpRequest的CORS校验,后端的重定向会被浏览器直接处理。

额外优化:后端CORS配置

如果你的后端使用了cors中间件,确保配置为指定前端域名而非通配符:

const cors = require('cors');
app.use(cors({
  origin: 'http://localhost:3000', // 替换为你的前端实际域名
  credentials: true // 若请求需要携带凭证(如cookie)则开启
}));

注:此配置仅针对后端自身接口,第三方支付平台的CORS规则无法修改,核心解决思路仍是避免让Ajax请求直接重定向到第三方域名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:44:56