跨源请求中的cookie


本文作者: jsweibo

本文链接: https://jsweibo.github.io/2020/01/30/%E8%B7%A8%E6%BA%90%E8%AF%B7%E6%B1%82%E4%B8%AD%E7%9A%84cookie/

摘要

本文主要讲述了:

  1. 背景
  2. 解决方案

正文

背景

默认情况下,浏览器不会为 Ajax 跨源请求提供 cookie,也不会接受 Ajax 跨源请求中服务器端要求写入的 cookie

解决方案

要解决这个问题,必须满足以下所有条件:

  1. 网页表示允许 Ajax 跨源请求读写 cookie
  2. 服务器端表示愿意接受 Ajax 跨源请求中的 cookie。若此条件不满足,则浏览器会发出跨源请求,但不会把 Ajax 跨源请求的响应交给客户端的 JavaScript(会报错)

要做到第一点:

  • 若使用XMLHttpRequest实例进行通信,则浏览器端需要将XMLHttpRequest实例的withCredentials设置为true
  • 若使用fetch()进行通信,则浏览器端需要将init对象的credentials属性设置为include

要做到第二点:

  • 若为简单请求,服务器端需要将Access-Control-Allow-Credentials设置为trueAccess-Control-Allow-Origin的值必须是具体的源而不能为*(请求头中包含认证信息)
  • 若为非简单请求,服务器端还需要将OPTIONS方法的Access-Control-Allow-Credentials响应头设置为trueAccess-Control-Allow-Origin的值必须是具体的源而不能为*(请求头中包含认证信息)

示例:为 Ajax 跨源请求提供 cookie,接受 Ajax 跨源请求中服务器端要求写入的 cookie

nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80;
server_name a.example.com;
location / {
root html/a.example.com;
index index.html;
}
}

server {
listen 80;
server_name b.example.com;
location / {
add_header Access-Control-Allow-Origin http://a.example.com;
add_header Access-Control-Allow-Credentials true;
root html/b.example.com;
index index.html;
}
}

使用XMLHttpRequest实例:

a.example.com/js/index.js

1
2
3
4
5
6
7
8
9
let xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function () {
if (xhr.readyState === XMLHttpRequest.DONE) {
console.log(xhr.response);
}
});
xhr.withCredentials = true;
xhr.open('GET', 'http://b.example.com/data.json');
xhr.send();

使用fetch()

a.example.com/js/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fetch('http://b.example.com/data.json', {
credentials: 'include',
})
.then(function (response) {
if (response.ok) {
return response.json();
} else {
console.log(response);
throw new Error('Request Error');
}
})
.then(function (data) {
console.log(data);
});

参考资料

本文作者: jsweibo

本文链接: https://jsweibo.github.io/2020/01/30/%E8%B7%A8%E6%BA%90%E8%AF%B7%E6%B1%82%E4%B8%AD%E7%9A%84cookie/


本文对你有帮助?请支持我


支付宝
微信