获取 - 响应预检请求

10

我在处理带有授权的CORS fetch时遇到了困难:

const token = 'this.is.secret!';
fetch('http://corsserver/api/hello', {
    method: 'get',
    credentials: 'include',
    mode: 'cors',
    headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/x-www-form-urlencoded'
    }
}).then(response => {
  console.log(response);
}).catch(error => {
  console.log(error);
});

当我运行此请求时,Chrome 将标头设置为:
请求方法:OPTIONS
我查了一下,这是一个预检请求
我的意思是,这真的很酷。但是,在预检请求返回 OK 后,我不知道如何发送实际请求!接下来该怎么办?如何发送 GET 请求?
我错过了非常基本的东西。

附带说明:似乎在发送GET请求时,不需要发送Content-Type请求头...因为在GET中没有内容体可提供内容类型。 - sideshowbarker
我猜测OPTIONS可能会失败,因为服务器要求对该OPTIONS请求进行身份验证。请参见我刚刚添加到答案中的更新。 - sideshowbarker
1个回答

11
如果OPTIONS请求成功,浏览器将自动发送实际的GET请求。但是如果OPTIONS请求失败,浏览器将不会执行GET请求。
而且没有办法在浏览器不执行OPTIONS请求的情况下执行GET请求。因此,如果浏览器不执行GET请求,只能说明OPTIONS请求失败了,需要找出原因。浏览器应该将原因记录在其开发工具控制台中,所以您应该从那里开始检查(然后要么编辑/更新问题以添加该信息,要么发布一个新的更具体的问题并包含错误消息)。
可能存在的问题之一是:服务器要求对OPTIONS请求进行身份验证。如果是这样,您需要修复它使得服务器不再需要验证——因为当浏览器发起OPTIONS请求时,它不会从您的代码中发送Authorization头+值。
事实上,OPTIONS请求在这种情况下完全的目的是让浏览器询问“你是否允许使用带有Authorization请求头的跨域请求?”并且服务器需要以指示其是否允许使用Authorization头的方式进行响应。
因此,由于这个原因,服务器必须配置为在任何OPTIONS请求(至少来自允许的来源)中以2xx成功响应而不需要身份验证。
您可以通过浏览器记录的CORS消息是否显示OPTIONS响应的401状态来确定服务器是否需要对该OPTIONS请求进行身份验证。
以下是在Node.js服务器环境中处理OPTIONS的示例代码:
if (req.method === 'OPTIONS') {
  res.send();
  return;
}

要让服务器发送一个没有响应体的200响应,这正是你想要的。请注意,这明确允许所有OPTION请求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接