获取失败:请求需要预检,不允许进行跨域重定向
Posted
技术标签:
【中文标题】获取失败:请求需要预检,不允许进行跨域重定向【英文标题】:Failed to fetch: Request requires preflight, which is disallowed to follow cross-origin redirect 【发布时间】:2017-05-16 15:54:44 【问题描述】:我正在使用 Express 作为网络服务器,并从客户端使用 isomorphic-fetch 模块来使用 XHR。
我的 Web 应用程序有三台服务器:
端口 3000 -> 管理网站 端口 3001 -> 公共网站 端口 3002 -> API 服务器API Server 有名为“skills”的资源,其中包含一些数据,并像这样获取它:
GET http://mydomain:3002/skills
它返回 JSON 数据。
但是当我从 3000/3001 请求到 3002 时,它会失败并显示以下消息:
Fetch API 无法加载 http://example.me:3002/skills。从“http://example.me:3002/skills”重定向到“http://example.me:3002/skills/”已被 CORS 政策阻止:请求需要预检,不允许进行跨域重定向。
我不明白为什么会有“重定向”之类的。这是我的服务器端代码,我授予了所有与 CORS 相关的标头:
const express = require('express');
const app = express();
...
// CORS
app.use((req, res, next) =>
var allowedOrigins = ['http://example.me', 'http://example.me:3000', 'http://example.me:3001', 'http://example.me:3002'];
var origin = req.headers.origin;
if(allowedOrigins.indexOf(origin) > -1)
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
if (req.method === "OPTIONS")
return res.status(200).end();
next();
);
app.use(require('./routes'));
...
app.listen(3002, () => console.log(".API Server listening on port 3002..."));
这是使用 Fetch API 的客户端代码:
fetch('http://example.com:3002/skills',
method: 'GET',
headers:
'Accept': 'application/json',
'Content-Type': 'application/json'
,
credentials: 'include',
cache: 'no-store',
mode: 'cors'
)...
如您所见,没有重定向代码。我花了将近一天的时间来解决这个问题,但我尝试的一切都失败了,我发现的每一个信息都是无用的。
我认为将服务拆分为 API Server 和 Web Server(实际上返回 html)是个好主意,并且希望采用这种方法。
有没有办法解决这个问题?任何建议都会非常感激。
【问题讨论】:
为什么要在 GET 请求中设置 Content-Type? 你在 3 个服务器上允许 Cors 吗? @Quentin 实际上我不记得为什么,我想我只是在某个地方看到了一些 fetch API 信息。我刚刚删除了那个标题。反正没关系,还是不行。 @Hosar 是的,当然。我允许他们三个。您可以在服务器端代码、cors 中间件部分检查这一点。 查看***.com/questions/34949492/… 的答案,了解如何解决此问题的详细信息。此外,正如那里所指出的,这种对重定向的限制不再在规范中,但浏览器需要更新其实现以匹配规范更改。 【参考方案1】:几年前我解决了这个问题,仍然不明白为什么会发生。
但是我的解决方案很简单,将每个 API 放入 /api 路径。
【讨论】:
以上是关于获取失败:请求需要预检,不允许进行跨域重定向的主要内容,如果未能解决你的问题,请参考以下文章
已完成 401 未授权请求被重定向到不允许需要预检的跨域请求
带有跨域重定向的 Safari xhr (AJAX) 请求失败