Cookie中不能有空格_Cookie实用方案及原理总结

392fdf68bf760120132e651771de9bdf.png

title: Cookie实用原理总结 date: 2019-09-10 21:47:56 categories: - 技术 - 原理 tags: - Web前端 - Cookie - 小技巧


前言

此篇文章需要你掌握有关 Javascript | Web | HTTP 的基础知识。阅读时长约为5分钟。

其实作为一名现代的前端开发者,Cookie 的这个概念几乎不用接触,这个是上个时代遗留下来的东西,了解它不乏有点困惑。但新的技术总是会与老技术相互碰撞,可能让后端自行带上 Token 等一些信息,Cookie 是一种最方便的方法了。所以本篇文章,我们就来讲讲 Cookie 有哪些有用的地方,与其他值得注意使用的地方。

一、Cookie 的出现

Cookie 的用途主要是用来解决 HTTP 无状态的问题,我们都知道 HTTP 是没有状态的,也就是说我们每次的请求其实都是无状态的,如果不是 Javascript 可以主动设置请求头等信息的话,服务器是基本无法知道你是谁的。所以一般 Cookie 结合服务端的Session 会话功能,可以在你浏览并登陆之后,直到你退出页面都知道你是谁,你的商品到底加入到了谁的购物车。

除了提供可持续的状态,Cookie 还可以支持你的离线后再次记住你的功能。因为 Cookie 是可以设置过期时间(但不能永久,主动的清除缓存也会失效)。可是这样看起来 Cookie 是不是过于强大了呢?所以其实不好好用 Cookie 可能会造成一些人的滥用,从而导致用户的信息被盗等问题。

二、Cookie 到底怎么用?

document.cookie = "yummy_cookie=choco;domain=.icanvip.net";

其实这一句代码就可以用了,虽然不怎么好用看起来,但是它包含了 Cookie 的读取与设置,所以非常好上手。

以下可选的 cookie 属性值可以跟在键值对后,用来具体化对 cookie 的设定/更新,使用分号以作分隔:
  • ;path=path (例如 '/', '/mydir') 如果没有定义,默认为当前文档位置的路径。
  • ;domain=domain (例如 'example.com', 'subdomain.example.com') 如果没有定义,默认为当前文档位置的路径的域名部分。与早期规范相反的是,在域名前面加 . 符将会被忽视,因为浏览器也许会拒绝设置这样的cookie。如果指定了一个域,那么子域也包含在内。
  • ;max-age=max-age-in-seconds (例如一年为60 * 60 * 24 *365)
  • ;expires=date-in-GMTString-format 如果没有定义,cookie会在对话结束时过期 这个值的格式参见Date.toUTCString()
  • ;secure (cookie只通过https协议传输)
cookie的值字符串可以用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).

上面也是摘自 https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie 说的也是十分清楚,cookie 有哪些值可以设置。

三、Cookie 中的Q&A

1. 能设置或读取子域的 cookie 吗?

不行! 只能向当前域或者更高级域设置 cookie

例如 client.com 不能向 a.client.com 设置 cookie , 而 a.client.com 可以向 client.com 设置 cookie

读取 cookie 情况同上

所以,如果你想在多个子域名下共享用户状态的话,可以利用这个原理进行对根域名的 Cookie 设置,这样其他子域名包含根域名的网址都可以读取到这个用户的状态。

2. 客户端设置 cookie 与服务端设置 cookie 有什么区别?

无论是客户端还是服务端, 都只能向自己的域或者更高级域设置 cookie 例如 client.com 不能向 server.com 设置 cookie , 同样 server.com 也不能向 client.com 设置 cookie 服务端可以设置 httpOnly: true, 带有该属性的cookie客户端无法读取 客户端只会带上与请求同域的 cookie, 例如 client.com/index.html 会带上 client.comcookie, server.com/app.js 会带上 server.comcookie, 并且也会带上 httpOnlycookie 但是, 如果是向服务端的 ajax 请求, 则不会带上 cookie , 详情见第三个问题

3. 同域/跨域ajax请求到底会不会带上 cookie ?

这个问题与你发起 ajax 请求的方式有关 fetch 在默认情况下, 不管是同域还是跨域 ajax 请求都不会带上 cookie , 只有当设置了 credentials 时才会带上该 ajax 请求所在域的 cookie , 服务端需要设置响应头 Access-Control-Allow-Credentials: true, 否则浏览器会因为安全限制而报错, 拿不到响应

fetch(url, {
    credentials: "include", // include, same-origin, omit
})

axiosjQuery 在同域 ajax 请求时会带上 cookie , 跨域请求不会, 跨域请求需要设置 withCredentials 和服务端响应头

js axios.get('http://server.com', {withCredentials: true})

```js $.ajax({ method: 'get', url: 'http://server.com', xhrFields: { withCredentials: true } })

以上原答案来自

> 作者:碎碎酱
链接:https://juejin.im/post/5b5df0aee51d451998415485
来源:掘金

# 四、最新的 Cookie 安全保证 --- Cookie 的 SameSite 属性

Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。
它可以设置三个值。
- Strict
- Lax
- None

## 1. Strict

 `Strict` 最为严格,完全禁止第三方 `Cookie`,跨站点时,任何情况下都不会发送 `Cookie`。换言之,只有当前网页的 `URL` 与请求目标一致,才会带上 `Cookie`。

Set-Cookie: CookieName=CookieValue; SameSite=Strict;

这个规则过于严格,可能造成非常不好的用户体验。比如,当前网页有一个 `GitHub` 链接,用户点击跳转就不会带有 `GitHub` 的 `Cookie`,跳转过去总是未登陆状态。
## 2. Lax
 `Lax` 规则稍稍放宽,大多数情况也是不发送第三方 `Cookie`,但是导航到目标网址的 Get 请求除外。

Set-Cookie: CookieName=CookieValue; SameSite=Lax;

导航到目标网址的 `GET` 请求,只包括三种情况:链接,预加载请求,`GET` 表单。详见下表。

http://www.ruanyifeng.com/blog/2019/09/cookie-samesite.html

设置了 `Strict` 或 `Lax` 以后,基本就杜绝了 `CSRF` 攻击。当然,前提是用户浏览器支持 `SameSite` 属性。

## 3. None

`Chrome` 计划将Lax变为默认设置。这时,网站可以选择显式关闭 `SameSite` 属性,将其设为 `None` 。不过,前提是必须同时设置 `Secure` 属性( `Cookie` 只能通过 `HTTPS` 协议发送),否则无效。

下面的设置无效。

Set-Cookie: widget_session=abc123; SameSite=None

下面的设置有效。

Set-Cookie: widget_session=abc123; SameSite=None; Secure ```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值