反应客户端不会跟随重定向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 ./dist
或pm2
运行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 将客户端重定向到不同的域?