本文作者: jsweibo
本文链接: https://jsweibo.github.io/2019/03/24/%E4%BB%80%E4%B9%88%E6%98%AFSet-Cookie/
摘要
本文主要讲述了:
- 什么是 Set-Cookie
- 语法
- 写入一个 Cookie
- 写入多个 Cookie
- 指令
正文
什么是 Set-Cookie
服务器端通过Set-Cookie
响应头在客户端写入 Cookie。
语法
1 | Set-Cookie: <cookie-name>=<cookie-value> |
写入一个 Cookie
示例:
1 | Set-Cookie: username=jsweibo |
写入多个 Cookie
写入多个 Cookie 时只需要返回多个Set-Cookie
即可。
示例:
1 | Set-Cookie: username=jsweibo |
指令
Expires 指令
服务器端可以使用Expires
指令来设定 cookie 的到期时间。
Expires
指令使用 GMT 时间。
如果不使用Expires
指令。Cookie 将在浏览器被关闭之后自动到期。
如果使用了Expires
指令。Cookie 将根据客户端时间来判断 cookie 是否到期。
示例:
1 | Set-Cookie: username=jsweibo; Expires=Wed, 01 Jan 2020 00:00:00 GMT |
Max-Age 指令
服务器端可以使用Max-Age
指令来设定再过多少秒 cookie 过期。
如果同时设置Expires
指令和Max-Age
指令,Expires
指令将被忽略。
示例:
1 | Set-Cookie: username=jsweibo; Max-Age=60 |
HttpOnly 指令
服务器端可以使用HttpOnly
指令禁止客户端使用document.cookie
来读写此 Cookie。
示例:
1 | Set-Cookie: username=jsweibo; HttpOnly |
Secure 指令
服务器端可以使用Secure
指令来指定客户端只在 https 请求时才发送 cookie 到服务器端。
注意:从 Firefox 52、Chrome 52 起,http 网站无法使用Secure
指令。
示例:
1 | Set-Cookie: username=jsweibo; Secure |
Domain 指令
服务器端可以使用Domain
指令来指定 cookie 的域名。
由于”同源政策 + Public Suffix List”的限制,浏览器端的 JavaScript 仅能读写部分第一方 cookie。
注意:cookie 的读写并未完全遵循同源政策。例如:
- 允许
a.example.com
读写domain=.example.com
的 cookie - 允许
https://a.example.com
读写http://a.example.com
的 cookie,反之亦然 - 允许
http://a.example.com:81
读写http://a.example.com:80
的 cookie
子域不可见的 cookie
在服务器响应头中,若不使用Domain
指令,客户端将直接存储服务器的域名。
示例:
example.com
1 | Set-Cookie: username=jsweibo |
客户端会以username=jsweibo;Domain=example.com
的形式存储。注意:此 cookie 无法被a.example.com
读写。
子域可见的 cookie
在服务器响应头中,若使用Domain
指令,客户端会在域名前添加.
而后存储。
示例:
example.com
1 | Set-Cookie: username=jsweibo;Domain=example.com |
客户端会以username=jsweibo;Domain=.example.com
的形式存储。注意:此 cookie 可被a.example.com
读写。
Path 指令
服务器端可以使用Path
指令来指定 cookie 的路径。
注意:只能向上读写。例如Path=/a
的 cookie 可以被/a/b
读写;Path=/a/b
的 cookie 无法被/a
读写
如果不使用此指令,默认取服务器文件的路径。
示例:
1 | Set-Cookie: username=jsweibo; Path=/test |
SameSite 指令
服务器端可以使用此指令设定是否在跨站请求时携带该 cookie。
注意:是否是跨站请求基于”Public Suffix List”判断。
示例:
测试环境:
example.com
1 |
|
由于”Public Suffix List”的限制,a.github.io
或github.io
均无法写入domain=.github.io
的 cookie,因此无法提供相应的测试环境。
结论:
a.example.com
中通往b.example.com
的网络请求不是a.example.com
的跨站请求a.example.com
中通往example.com
的网络请求不是a.example.com
的跨站请求a.example.com
中通往a.foo.com
的网络请求是a.example.com
的跨站请求a.example.com
中通往foo.com
的网络请求是a.example.com
的跨站请求a.github.io
中通往b.github.io
的网络请求是a.github.io
的跨站请求a.github.io
中通往github.io
的网络请求是a.github.io
的跨站请求
SameSite
指令有 3 种取值:
None
Strict
Lax
None
- 在同站请求中携带该 cookie
- 在跨站请求中携带该 cookie
注意:须配合Secure
指令使用
Strict
- 在同站请求中携带该 cookie
- 在跨站请求中拒绝携带该 cookie
Lax
- 在同站请求中携带该 cookie
- 在页面跳转的跨站请求中(例如:
<a>
、location.href
)携带该 cookie,在其他的跨站请求中拒绝携带该 cookie
参考资料
本文作者: jsweibo
本文链接: https://jsweibo.github.io/2019/03/24/%E4%BB%80%E4%B9%88%E6%98%AFSet-Cookie/
本文对你有帮助?请支持我
- 本文链接: https://jsweibo.github.io/2019/03/24/%E4%BB%80%E4%B9%88%E6%98%AFSet-Cookie/
- 版权声明: 除非另有说明,否则本网站上的内容根据署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。