【问题标题】:fetch() request is send twice with credentials, no preflightfetch() 请求使用凭据发送两次,没有预检
【发布时间】:2018-01-25 01:06:34
【问题描述】:

我正在使用fetch 从我的休息服务器获取数据,并且我在客户端使用这个带有 Javascript 的查询:

            return fetch(
            "http://localhost:443/myressource",  {
            method: 'GET',
            mode: 'no-cors',
            credentials : 'include',
            headers: {
                "Authorization":"Basic " + btoa("test:test"),
                "Accept-Encoding": "gzip, deflate"
            }})
           .then(response => response.text())
           .catch(err => { throw err })

问题在于第一个请求已经包含凭据,通常当您发送请求时,第一个请求没有凭据,您必须在服务器端设置一个领域,然后浏览器应该发送凭据。

有没有办法让 fetch 工作正常?意思是在需要时发送凭据?

【问题讨论】:

  • .catch(err => { throw err }) 什么都不做。
  • 或者更确切地说,做一些事情,但它纯粹是开销而不改变最终结果。
  • @SLaks 我在另一个函数中有 .catch(err => console.error(err))。
  • @John:这很好,但.catch(err => { throw err;}) 除了引入不必要的开销之外,真的没有其他目的。

标签: javascript fetch-api


【解决方案1】:

不是 100% 了解您如何确定何时需要它们,但您可以执行以下操作:

let config = {
  method: 'GET',
  mode: 'no-cors',
  credentials: 'include',
};

if (neededCondition) {
  config.headers = {
    "Authorization": "Basic " + btoa("test:test"),
    "Accept-Encoding": "gzip, deflate"
  };
} 

return fetch( "http://localhost:443/myressource", config)
  .then(response => response.text())

也许这可以通过使用 sessionStorage 并检查那里是否存在凭据来确定

【讨论】:

  • 实际上我找到了正确的词,它叫做“预检”,意思是当浏览器发送请求时,第一个请求是要求获得执行操作的权限,第二个请求包含所有信息。这不是客户端逻辑,而是请求对 cors 请求的正常工作方式。
  • 是...并且通过设置自定义标头,当端点来源与页面不同时,浏览器将始终触发 OPTIONS(预检)请求
  • 我在标题中添加了这个:'x-my-custom-header': 'some value',但它仍然没有执行预检。而且我注意到,如果我删除 mode: no-cors ,则 fetch 会发送两次 OPTION 请求。使用 mode: no-cors 他发送了两次 GET 请求。
  • 哦,是的......老实说,我没有使用 fetch 太多,因为它仍然不是 100% 支持的跨浏览器,并且忘记了我仍然不太了解的 no-cors 模式
猜你喜欢
  • 2012-02-24
  • 2018-10-31
  • 2019-10-12
  • 2019-09-02
  • 2012-04-07
  • 1970-01-01
  • 2017-05-31
  • 2021-10-22
  • 2019-05-15
相关资源
最近更新 更多