我正在尝试使用新的Fetch API,但在处理Cookies时遇到了问题。具体来说,在成功登录后,未来请求中会有一个Cookie头部,但Fetch似乎忽略了该头部,因此我用Fetch发出的所有请求都被拒绝。
这是因为Fetch还没有准备好,还是Fetch不能与Cookies一起使用?
我用Webpack构建我的应用程序。我也在React Native中使用Fetch,但没有同样的问题。
默认情况下,Fetch 不使用 cookie。要启用 cookie,请按照此方法进行操作:
fetch(url, {
credentials: "same-origin"
}).then(...).catch(...);
除了@Khanetor的回答外,对于那些处理跨域请求的人: credentials: 'include'
示例JSON获取请求:
fetch(url, {
method: 'GET',
credentials: 'include'
})
.then((response) => response.json())
.then((json) => {
console.log('Gotcha');
}).catch((err) => {
console.log(err);
});
https://developer.mozilla.org/zh-CN/docs/Web/API/Request/credentials
document.cookie
中设置值即可将其包含在请求中。 - skwidbrethAccess-Control-Allow-Credentials
的CORS问题,请确保在Rack :: Cors配置中将资源上的credentials:true
设置。 - Mathyou我刚刚解决了。只用了两天的暴力破解。
对我来说,秘诀在于以下几点:
我调用了 POST /api/auth 并查看到 cookies 已成功接收。
然后调用 GET /api/users/ 并使用 credentials: 'include'
,但由于没有发送任何 cookies,因此得到 401 未经授权的状态码。
关键是设置第一个 /api/auth
调用的 credentials: 'include'
。
如果您在2019年阅读此内容,credentials: "same-origin"
是默认值。
fetch(url).then
在浏览器端以编程方式覆盖Cookie
头文件不起作用。
在fetch
文档中,提到了某些名称是被禁止的。而Cookie
恰好是其中一个被禁止的标头名称,无法通过编程方式修改。例如,请看以下代码:
Cookie:'xxx=yyy'
,则会被忽略,并且如果存在cookie,则浏览器将始终将document.cookie
的值作为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
。
有关详细信息,请参见禁止使用的标头名称。
以下是针对 .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)));
};
}
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
真是救了我一命! - Andrew/auth
),但我正在不同的路径上进行fetch
。我需要将我的cookie的path
设置为/
。fetch
没有发送凭据,可能是因为请求由于请求的源和响应位置之间的协议差异而被处理为跨域。http
URL的Location
头部,而连接是通过https
建立的。结果,浏览器将请求视为跨域并应用跨域规则。值得注意的是,Firefox(版本114.0.2)和Safari(版本16.1)在这种情况下没有显示任何警告,但Chrome(版本114.0.5735.198)显示了一个(blocked:mixed-content)
错误,这有助于识别问题。gunicorn
服务器没有正确处理它,具体涉及到secure-scheme-headers
和forwarded_allow_ips
设置。在解决了服务器端的这些设置后,fetch
在所有浏览器中都正常工作了。
same-origin
(仍然有效)意味着更多的标头将得到尊重(如cookies等),但您的代码无法完全访问响应内容。 - Codererdocument.cookie
读取,但仍然可以在ajax或fetch请求中使用。 - Martin Bajcar