Fetch - 响应预检响应

Posted

技术标签:

【中文标题】Fetch - 响应预检响应【英文标题】:Fetch - respond to preflight response 【发布时间】:2018-01-05 19:16:35 【问题描述】:

我正在努力通过 CORS 获取授权:

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 将标头设置为:

Request Method:OPTIONS

我查了一下,it's a preflighted request。

我的意思是,这真的很酷。但是我不知道在预检回来后如何发送实际请求好吧!下一步是什么?如何发送 GET 请求?

我在这里遗漏了一些非常基本的东西。

【问题讨论】:

附带点:似乎没有必要为 GET 请求发送 Content-Type 请求标头……GET 中没有正文来提供内容类型…… 我猜 OPTIONS 可能会失败,因为服务器需要对该 OPTIONS 请求进行身份验证。查看我刚刚添加到答案的更新 【参考方案1】:

如果OPTIONS 请求成功,您的浏览器将自动发送实际的GET 请求。但是如果OPTIONS请求不成功,浏览器将永远不会发出GET请求。

如果浏览器不发出OPTIONS 请求,就没有其他方法可以发出GET 请求。

所以如果浏览器没有发出GET 请求,那只能说明OPTIONS 一定失败了,你需要找出原因。浏览器应该将带有原因的消息记录到其 devtools 控制台,因此您应该首先检查那里(然后编辑/更新问题以添加该信息,或者发布一个新的单独的更具体的问题以及错误消息) .


猜测可能是什么问题:可能服务器要求对OPTIONS 请求进行身份验证。如果是这样,您需要修复它以使服务器不会 - 因为当浏览器发出 OPTIONS 请求时,它不会从您的代码中发送 Authorization 标头+值。

实际上,在这种情况下,OPTIONS 请求的全部目的是让浏览器询问,您是否可以获取包含 Authorization 请求标头的跨域请求?,并让服务器以指示它是否允许 Authorization 标头的方式进行响应。

因此,服务器必须配置为以 2xx 成功响应响应任何 OPTIONS 请求(至少来自允许的来源),而无需身份验证。

如果您的浏览器正在记录的 CORS 错误消息显示 OPTIONS 响应的 401 状态,您就会知道服务器是否需要对该 OPTIONS 请求进行身份验证。


在 Node.js 服务器环境中处理 OPTIONS 的示例代码:

if (req.method === 'OPTIONS') 
  res.send();
  return;

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

【讨论】:

以上是关于Fetch - 响应预检响应的主要内容,如果未能解决你的问题,请参考以下文章

React Express Fetch Post CORS 错误:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

浏览器预检,后台响应(转载)

“预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段模式”如何解决 Apollo 的问题?

CORS 预检响应错误

CORS 预检响应如何实际缓存在浏览器中?

CORS 预检响应未成功