获取失败:请求需要预检,不允许进行跨域重定向

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) 请求失败

该请求被重定向到“https://..com/site/login?”,这对于需要预检的跨域请求是不允许的

如何解决“预检无效(重定向)”或“预检请求不允许重定向”

如何解决“预检无效(重定向)”或“预检请求不允许重定向”

CORS:对预检请求的响应未通过访问控制检查:预检请求不允许重定向