Cookie 和 Session
Cookie
作用
- 登录、购物车、游戏分数
- 用户个性化信息、主题、其他设置
- 记录和分析用户行为
创建 Cookie
服务器在返回网页内容的时候,使用 Set-Cookie
头来创建 Cookie
:
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]
Cookie 的有效期
- Session:浏览器关闭当前
Tab
页就过期 - Expires 和 Max-Age
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Cookie 访问权限
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
- Secure:只有 HTTPS 协议的时候,浏览器端的 Cookie 才会上传到 Server
- HttpOnly:声明这个的 Cookie,使用
Document.cokie
无法读和写
JavaScript 读写 Cookie
document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);
Cookie 共享
a.jd.com
能否共享jd.com
的 Cookie?a.jd.com
和b.jd.com
呢?
同域名的二级域名可以实现共享,比如 www.domain.com
登陆后,在其他的二级域名,如 my.domain.com
、bj.domain.com
、sh.domain.com
等二级域名都是可以共享登录的 Cookie 的。
mydomain.com
和 subdomain.mydomain.com
只能通过服务器端 Set-Cookie
头的方式来共享 Cookie;默认情况下,它们各自的 Cookie 的作用域都仅局限于请求的 Host,也称之为 Host-only Cookie。不过如果你主动设置了 domain
:
Set-Cookie: name=value; domain=mydomain.com
那么任何 mydomain
的 subdomain
,都可以共享此 Cookie,比如 subsub.subdomain.mydomain.com
。In RFC 2109, a domain without a leading dot meant that it 不能够 used on subdomains, and only a leading dot (.mydomain.com
) would allow it to be used across multiple subdomains. However, all modern browsers respect the newer specification RFC 6265, and 会忽略任何的前缀 .
, meaning you can use the cookie on subdomains as well as the top-level domain.
另外还有一个需要注意的点就是:从 subdomain.mydomain.com
返回的响应中带有 Set-Cookie: name=value; Domain=mydomain.com
,是没有问题的;但是如果从 mydomain.com
返回的响应中带有 Set-Cookie: name=value; Domain=subdomain.mydomain.com
,就会被浏览器拒绝掉这样的 Cookie。
Session
Java 服务器端的 Session 对象
如下是在 Java 中 javax.servlet.http.HttpSession
接口中的两个方法:
public interface HttpSession {
void setAttribute(String name, Object value);
Object getAttribute(String key);
}
在 Tomcat 中的 StandardSession
内部实现:
public class StandardSession implements HttpSession, Session, Serializable {
protected ConcurrentHashMap<String, Object> attributes = new ConcurrentHashMap();
@Override
public void setAttribute(String name, Object value) {
this.attributes.put(name, value);
}
@Override
public Object getAttribute(String name) {
return this.attributes.get(name);
}
}
可见 Session
其实就是一个存储在服务器端的 Map
,它可以存储的对象为 Object
。
Session 默认有效期
在 Tomcat 中,Session
默认有效期是 30 秒:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
Session vs Cookie
- 安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
- 存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。
- 有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
- 存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。