我正在尝试新的Fetch API,但cookie有问题。具体来说,在成功登录后,在未来的请求中有一个Cookie报头,但Fetch似乎忽略了这个报头,并且我所有的请求都是未经授权的。

是因为Fetch还没有准备好,还是Fetch不能与cookie一起工作?

我用Webpack构建我的应用程序。我也在React Native中使用Fetch,它没有同样的问题。


当前回答

这对我来说很管用:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

然后构建你的调用:

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }

其他回答

在浏览器端以编程方式重写Cookie报头将不起作用。

在获取文档中,注意一些名称是禁止的。提到。Cookie恰好是被禁止的头名称之一,不能通过编程方式修改。以下面的代码为例:

在Chrome DevTools控制台https://httpbin.org/页面执行,Cookie: 'xxx=yyy'将被忽略,浏览器将始终发送document的值。如果有饼干的话,那就是饼干。 如果在不同的源上执行,则不会发送cookie。

fetch('https://httpbin.org/cookies', {
  headers: {
    Cookie: 'xxx=yyy'
  }
}).then(response => response.json())
.then(data => console.log(JSON.stringify(data, null, 2)));

附注:你可以通过在chrome浏览器中打开https://httpbin.org/cookies/set/foo/bar来创建一个示例cookie foo=bar。

有关详细信息,请参阅禁止的头名称。

默认情况下,Fetch不使用cookie。要启用cookie,请执行以下操作:

fetch(url, {
  credentials: "same-origin"
}).then(...).catch(...);

只是为。net webapi2用户添加了正确的答案。

如果你使用cors是因为你的客户端站点和你的webapi来自不同的地址,那么你还需要在服务器端配置中包含SupportsCredentials=true。

        // Access-Control-Allow-Origin
        // https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
        var cors = new EnableCorsAttribute(Settings.CORSSites,"*", "*");
        cors.SupportsCredentials = true;
        config.EnableCors(cors);

如果它仍然不能为您修复凭证后。

我还用了:

  credentials: "same-origin"

它曾经工作,然后它不再突然,在挖掘了很多之后,我意识到我已经把我的网站url更改为http://192.168.1.100来测试它在局域网,这是用来发送请求的url,即使我是在http://localhost:3000上。

总之,要确保页面的域与获取url的域相匹配。

这对我来说很管用:

import Cookies from 'universal-cookie';
const cookies = new Cookies();

function headers(set_cookie=false) {
  let headers = {
    'Accept':       'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
};
if (set_cookie) {
    headers['Authorization'] = "Bearer " + cookies.get('remember_user_token');
}
return headers;
}

然后构建你的调用:

export function fetchTests(user_id) {
  return function (dispatch) {
   let data = {
    method:      'POST',
    credentials: 'same-origin',
    mode:        'same-origin',
    body:        JSON.stringify({
                     user_id: user_id
                }),
    headers:     headers(true)
   };
   return fetch('/api/v1/tests/listing/', data)
      .then(response => response.json())
      .then(json => dispatch(receiveTests(json)));
    };
  }