反应客户端不会跟随重定向CORS localhost

Posted

技术标签:

【中文标题】反应客户端不会跟随重定向CORS localhost【英文标题】:react client wont follow redirect CORS localhost 【发布时间】:2021-07-06 12:52:21 【问题描述】:

前端:localhost:3000 (react app) App.js (client) on load call api '/'

function fetch_redirect() 
  fetch("http://localhost:8082")


function App() 
  return <div className="App">fetch_redirect()</div>;


export default App;

后端:localhost:8082 (nodejs express app) 发送重定向到客户端上的 /test 端点

const express = require('express')
const app = express()
const cors = require('cors');

const whitelist = ['http://localhost:3000']
const corsOptions = 
  origin: function (origin, callback) 
      console.log(origin, whitelist.indexOf(origin) !== -1);
    if (whitelist.indexOf(origin) !== -1) 
      callback(null, true)
     else 
      callback(new Error('Not allowed by CORS'))
    
  


app.use(cors(corsOptions))
app.get('/', function (req, res) 
          res.redirect('http://localhost:3000/test')
    )
     
    app.listen(8082)

主要问题出在客户端 (react) 调用 API 后,重定向被阻止...如何让客户端响应应用程序遵循此重定向到 'http:/ /localhost:3000/test' 我的后端已经有了 cors,并启用了 localhost:3000 的白名单,以允许我不阻止 API 调用...但是 redirect 现在已从 fetch 前端阻止强>!

错误详情: CORS 策略已阻止从源“http://localhost:3000”访问“http://localhost:3000/test”(从“http://localhost:8082/”重定向)获取:无“访问” -Control-Allow-Origin' 标头存在于请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

【问题讨论】:

你用什么来运行 react 应用程序?我复制了您的代码并使用vite 运行客户端,一切正常。您可能需要修改您的5 客户端开发服务器 使用 npm start 命令创建-react-app 为了完成这项工作,我认为您需要更改 localhost:8082 快速代码以允许所有来源 - 而不仅仅是 http://localhost:3000。原因是,当请求跨源重定向时,浏览器会将 Origin 请求标头设置为 null。所以当localhost:8082 express代码看到请求时,Origin的值是null,而不是http://localhost:3000 【参考方案1】:

为了方便开发并拥有更接近生产环境的开发环境(无需使用Access-Control-Allow-Origin 降低安全级别),您应该有一个唯一的前端和后端入口点,与一个独特的来源(http://localhost:3000 在您的情况下)。

要实现这一点,请删除所有 Access-Control-* 标头,创建一个 src/setupProxy.js 文件并像这样填充它:

const  createProxyMiddleware  = require("http-proxy-middleware");

module.exports = app => 
  app.use(
    "/api",
    createProxyMiddleware (
      target: "http://localhost:8082",
      changeOrigin: true
    )
  );
;

然后用npm install --save-dev http-proxy-middleware安装所需的express中间件作为开发依赖

注意:此功能适用于 react-scripts@2.0.0 及更高版本。

最后,将前端的所有fetch 替换为以/api 开头的相对URL

fetch("http://localhost:8082") 变为 fetch('/api')) 像fetch('http://localhost:8082/some-endpoint') 这样的东西会变成fetch('/api/some-endpoint')

有关此的更多信息,请参阅docs。

【讨论】:

【参考方案2】:

尝试像这样重构你的代码:

const express = require('express')
const app = express()
const cors = require('cors');


const whitelist = ['http://localhost:3000', 'http://localhost:8082'];


const corsOptionsDelegate = (req, callback) => 
  var corsOptions;
  if (whitelist.indexOf(req.header('Origin')) !== -1) 
    corsOptions =  origin: true ;
   else 
    corsOptions =  origin: false ;
  
  callback(null, corsOptions);
;

const corsWithOptions = cors(corsOptionsDelegate);

app.route('/')
  .options(corsWithOptions, (req, res) =>  res.sendStatus(200); )
  .get(cors(), (req, res)=>
       res.redirect('http://localhost:3000/test')
);


app.listen(8082)

【讨论】:

【参考方案3】:

尝试在app.get 中使用next 函数:

app.get('/', function (req, res, next) 
  res.redirect('http://localhost:3000/test');
  next();
)

此外,对于您的 ReactJS 应用程序(我不确定您的实现、CSR 或 s-s-r),您应该添加两件事:

Webpack:传递 CORS 的代理 企业社会责任:
devServer: 
  ...
  headers: 
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
  

s-s-r:将上述标头添加到webpackDevMiddleware 选项中。 路线: CSR:用于在开发端运行项目,使用:
devServer: 
   historyApiFallback:
     index:'build/index.html'
   ,
,
对于 prod 端,使用spa 运行标志,例如serve 使用serve -s ./distpm2 运行pm2 start ./dist --spa。 s-s-r:无需添加额外配置。

【讨论】:

【参考方案4】:

试试这样的:

whitelistedOrigins = ['http://localhost:3000'];
app.use(cors(
    origin: whitelistedOrigins,
    methods: ['GET', 'PATCH', 'PUT', 'POST', 'DELETE', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
));

您可以根据需要修改方法/allowedHeaders 键...

编辑:您的后端是:3000,不是问题吗?客户端不能同时在3000。

【讨论】:

后端在8082,前端在3000

以上是关于反应客户端不会跟随重定向CORS localhost的主要内容,如果未能解决你的问题,请参考以下文章

CORS 请求重定向失败

如何让我的快速服务器使用 cors 将客户端重定向到不同的域?

如何在 nodejs express 重定向上启用 CORS?

从 JS 调用 CORS 错误的 Golang 重定向

注销重定向时出现 Keycloak CORS 问题

IIS Http 重定向