JavaScript Cookie 详解

JavaScript 中的 Cookie 是一种用于在浏览器和服务器之间传递数据的机制。它通常用于跟踪用户的会话信息,如登录状态、购物车内容等。

用法

设置Cookie

设置username='jack'的cookie

document.cookie = 'username=jack';

封装下:

function setCookie(name, value) {  
    document.cookie = name + "=" + (value || "") + "; path=/";  
}  

setCookie('password', 123);

.

设置有过期时间的Cookie

可以通过设置cookie的expires属性来为其指定一个终止日期。

expires属性应该是一个GMT格式的日期字符串,表示cookie的过期时间。

当浏览器的时间达到这个过期时间时,cookie就会被自动删除。

例如,设置一个名为myCookie的cookie,值为myValue,7天后过期:

function setCookieWithExpiration(name, value, daysToExpire) {  
    var date = new Date();  
    date.setTime(date.getTime() + (daysToExpire * 24 * 60 * 60 * 1000)); // 设置过期时间为指定的天数之后  
    var expires = "; expires=" + date.toUTCString(); // 转换为GMT格式的字符串  
    document.cookie = name + "=" + (value || "") + expires + "; path=/"; // 设置cookie  
}  
  
// 使用示例  
setCookieWithExpiration('myCookie', 'myValue', 7); // 

.

读取Cookie

读取 Cookie 同样是通过 document.cookie 属性进行的。这个属性会返回一个包含所有 Cookie 的字符串,每个 Cookie 之间用分号和空格分隔。

假设cookie中存储的内容为:username =jack;password=123

function getCookie(name) {  
    const value = `; ${document.cookie}`;  
    const parts = value.split(`; ${name}=`);  
    if (parts.length === 2) return parts.pop().split(';').shift();  
}  

getCookie(username)  // jack
getCookie(password)  // 123

.

删除Cookie

直接把expires属性指定一个过去的时间,cookie就会被自动删除

  1. 删除一个 Cookie:
    只需将其过期时间设置为一个过去的时间即可。例如:

    function deleteCookie(name) {     
        document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';  
    }  
    
    deleteCookie('password');
    
  2. 删除所有Cookie:
    可以编写一个函数来遍历当前所有的cookies,并为每一个设置过期时间为过去的时间。

    function deleteAllCookies() {  
        var cookies = document.cookie.split(";");  
      
        for (var i = 0; i < cookies.length; i++) {  
            var cookie = cookies[i];  
            var eqPos = cookie.indexOf("=");  
            var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;  
            document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";  
        }  
    }  
      
    // 使用示例  
    deleteAllCookies();
    

.

判断是否存在指定的Cookie

function hasCookie(name) {  
    var nameEQ = name + "=";  
    var ca = document.cookie.split(';');  
    for(var i=0;i < ca.length;i++) {  
        var c = ca[i];  
        while (c.charAt(0)==' ') c = c.substring(1,c.length);  
        if (c.indexOf(nameEQ) == 0) return true;  
    }  
    return false;  
} 

hasCookie('password');  // 不存在返回false
hasCookie('username'); // 存在返回true

.

插件

  1. jquery插件
    地址:http://apps.bdimg.com/libs/jquery.cookie/1.4.1/jquery.cookie.js

    // 写入cookie  
    $.cookie('name', 'value', { expires: 7 });  
      
    // 读取cookie  
    var value = $.cookie('name');  
      
    // 删除cookie  
    $.cookie('name', null);
    
  2. webpack插件
    npm install js-cookie --save
    yarn add js-cookie

    import Cookies from 'js-cookie';  
      
    // 设置cookie  
    Cookies.set('name', 'value');  
      
    // 获取cookie  
    const name = Cookies.get('name');  
      
    // 删除cookie  
    Cookies.remove('name');
    

Set-Cookie 响应头

字段名类别描述示例
Name常见Cookie的名称UserID
Value常见Cookie的值123456
Expires有效期Cookie的过期日期/时间Expires=Wed, 21 Oct 2023 07:28:00 GMT
Max-Age有效期定义Cookie生命周期的秒数(如果设置,将覆盖Expires)Max-Age=86400 (1天)
Domain作用域限制哪些可以接收CookieDomain=example.com
Path作用域限制哪些路径下的页面可以接收CookiePath=/users
Secure安全性限制Cookie只能通过HTTPS传输Secure
HttpOnly安全性限制JavaScript访问(即无法通过document.cookie访问)HttpOnly
SameSite安全性控制Cookie的跨站策略SameSite=LaxSameSite=StrictSameSite=None

Set-Cookie 是一个 HTTP 响应头,用于向客户端(通常是浏览器)发送一个或多个 cookie。

当浏览器接收到带有 Set-Cookie 头的响应时,它会将这些 cookie 存储起来,并在后续的请求中将其发送回服务器。

1. 有效期(Expires、Max-Age)

在HTTP 响应头中可以通过设置 Set-CookieExpiresMax-Age 两个属性来设置Cookie 的有效期

若 Cookie 过期,则这个 Cookie 会被删除,并不会发送给服务端。

Expires(GMT - 时间点)

Expires 是 HTTP 响应头中的一个字段,用于指定 Cookie 的过期日期和时间。

当浏览器收到带有 Expires 字段的 Set-Cookie 头部时,它会记住这个日期和时间,并在到达该日期后自动删除相应的 Cookie。

  1. 设置 Expires:

    当服务器想要设置一个带有特定过期日期的 Cookie 时,它会在响应头中添加 Set-Cookie 字段,并附带 Expires 属性。
    Expires 的值应该是一个格林威治标准时间(GMT)格式的日期和时间字符串,表示 Cookie 的过期时间。

    Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2030 07:28:00 GMT;
    

    上例中:id 是 Cookie 的名称,值为a3fWa,而 Expires=Wed, 21 Oct 2023 07:28:00 GMT 表示这个 Cookie 将在 2030 年 10 月 21 日 07:28:00 GMT 过期。

  2. Expires 的值:

    • Expires 的值必须是一个完整的日期和时间,包括年、月、日、时、分、秒和时区。
    • 如果 Expires 的日期早于当前日期,浏览器会立即删除这个 Cookie。
    • 如果 Expires 的日期是未来的某个时间点,浏览器会在那个时间点删除这个 Cookie。

.

Max-Age(秒 - 时间段)

Max-Age 是一个 HTTP 头部指令,用于定义 Cookie 的生存时间,即 Cookie 在客户端保持有效的时间长度。单位是秒。

在客户端 JavaScript 中,你可以使用 document.cookie 来读取和写入 Cookie,但无法直接设置 Max-Age。
Max-Age 必须在服务器端的响应头中设置。然而,你可以通过 AJAX 请求或其他方式与服务器通信,从而间接地控制 Max-Age 的值。

当浏览器收到服务器返回的包含 Max-AgeSet-Cookie 头部时,它会根据这个值来决定何时过期并删除这个 Cookie。

  1. 设置 Max-Age:
    当服务器想要设置一个带有特定生存时间的 Cookie 时,它会在响应头中添加 Set-Cookie 字段,并附带 Max-Age 属性。例如:

    Set-Cookie: id=a3fWa; Max-Age=604800;
    

    在这个例子中,id 是 Cookie 的名称,a3fWa 是它的值,而 Max-Age=604800 表示这个 Cookie 将在 604,800 秒(即7天)后过期。

  2. Max-Age 的值:

    • 如果 Max-Age 为正数,浏览器会将其持久化到对应的 Cookie 文件中。
      这意味着即使浏览器关闭或电脑重启,只要还在 Max-Age 指定的秒数之内,这个 Cookie 仍然是有效的。
      例如:Max-Age=604800; 表示604800 秒内有效,与浏览器重启无关

    • 如果 Max-Age 为负数,那么这个 Cookie 只会存在于当前浏览器会话中。
      一旦浏览器窗口或标签页关闭,这个 Cookie 就会立即失效。
      例如:Max-Age=-1; 浏览器重启后Cookie消失

    • 如果 Max-Age 为 0,浏览器会立即删除这个 Cookie。
      例如:Max-Age=0; 浏览器立即删除Cookie

.

优先级(Max-Age 高于 Expires )

  • Expires 字段的值是基于特定的日期和时间,它可能会受到时钟偏差和时区设置的影响。是个时间点
  • Max-Age字段的值只依赖于秒数,而不是具体的日期和时间。是个时间段

如果响应头中同时存在 Expires 和 Max-Age 属性,那么 Max-Age 将具有更高的优先级
浏览器会优先使用 Max-Age 来确定 Cookie 的过期时间。


2. 作用域(Domain、Path)

在HTTP 响应头中可以通过设置Set-CookieDomainPath两个属性来设置Cookie 的作用域。

Cookies的作用域是指Cookie在哪些URL或域名下是有效和可访问的。

Set-Cookie: name=value; Domain=.example.com; Path=/; 

Domain(域)

Domain属性定义了哪些域名可以接收该Cookie。 默认情况下,Cookie只能被设置它的那个域名(不包括子域名)所访问。

例如,如果Cookie是由example.com设置的,那么它只能被example.com访问,而不能被subdomain.example.com或其他任何域名访问。

然而,通过显式设置Domain属性,可以使Cookie对某个域及其所有子域都有效。

例如,如果Cookie的Domain被设置为.example.com注意前面的点),那么它将被example.comsubdomain.example.comanothersubdomain.example.com等所有子域所共享。

.

Path(路径)

Path属性定义了Cookie在哪个URL路径下是有效的。它指定了一个URL路径前缀,只有以这个前缀开头的URL才能访问该Cookie。

例如,如果Cookie的Path被设置为/myapp/,那么只有example.com/myapp/example.com/myapp/somepage等路径下的页面才能访问这个Cookie。

默认情况下,如果不设置Path属性,Cookie将只对设置它的那个页面(及其子路径)有效。


3. 安全性(HttpOnly、Secure、Samesite)

CSRF/XSRF 跨站请求伪造攻击
XSS 跨站脚本攻击

在HTTP响应头中可以通过设置Set-CookieHttpOnlySecureSamesite三个属性来设置Cookie的安全性。

由于Cookies可以存储用户的敏感信息,因此它们的安全性至关重要。

HttpOnly

可以防止客户端脚本(如JavaScript)访问Cookie,即无法通过 document.cookie 访问,从而降低跨站脚本攻击(XSS) 的风险(不能直接防止CSRF攻击)。

禁止js访问Cookie: (防止跨站脚本攻击(XSS))

Set-Cookie: userID=JohnDoe; HttpOnly

.

Secure

确保Cookie只能通过HTTPS协议传输,这有助于防止Cookie在不安全的网络中被截获。

Cookie只能通过HTTPS协议传输:

Set-Cookie: userID=JohnDoe; Secure

.

Samesite

用来标明这个cookie是否是“同站cookie”。同站cookie只能在本域名中使用,不能作为第三方cookie, 限制第三方Cookie,从而帮助减少安全风险

设置为同站cookie,同站cookie只能在本域名中使用 。(防止跨站请求伪造攻击(CSRF))

SameSite 可以设置为 StrictLaxNone

  • Strict:
    浏览器将只在同站点请求中发送 cookie(即,请求的目标 URL 与设置 cookie 的 URL 完全匹配)。

    Set-Cookie: userID=JohnDoe; SameSite=Strict
    
  • Lax :
    浏览器将在同站点请求和顶级导航(即,通过链接跳转到的页面)中发送 cookie。

    Set-Cookie: userID=JohnDoe; SameSite=Lax
    
  • None:
    浏览器将在所有请求中发送 cookie,但你必须同时使用 Secure 属性。

    Set-Cookie: userID=JohnDoe; SameSite=None; Secure
    

.

4. 服务端设置 Set-Cookie

在Java Servlet中,你可以使用Cookie类的构造函数和 setMaxAge()、setPath()、setSecure()、setHttpOnly() 方法来设置Cookie:

Cookie cookie = new Cookie("cookieName", "cookieValue");  
cookie.setMaxAge(60 * 60 * 24); // 设置有效期为30天  
cookie.setSecure(true); // 设置Secure属性:仅通过HTTPS传输  
cookie.setHttpOnly(true); // 设置HttpOnly属性:防止JavaScript访问  
cookie.setSameSite("Strict"); // 设置SameSite属性为Strict  
response.addCookie(cookie); // 将Cookie添加到响应中

这样当服务器响应客户端请求时,就会在HTTP响应头中包含这些设置了属性的Cookie。

以百度的 Cookies 为例:
在这里插入图片描述


缺点

Cookie 的确是一种非常有用的技术,用于在客户端存储和跟踪用户会话信息。

然而,它们也有一些缺点和潜在的问题,以下是一些主要的缺点:

  1. 隐私问题:
    Cookie 可以存储用户的个人信息,如果这些信息被不当处理或传输不安全,可能会泄露用户的隐私。
    一些用户可能不喜欢网站在他们计算机上存储信息,这可能会引发信任问题。

  2. 安全问题:
    如果 Cookie 没有正确设置 Secure 属性,它们可能会通过不安全的 HTTP 连接被传输,这可能导致会话劫持(session hijacking)等安全问题。
    如果没有设置 HttpOnly 属性,客户端脚本(如 JavaScript)可以访问 Cookie,这增加了跨站脚本攻击(XSS)的风险。

  3. 大小限制:
    每个 Cookie 的大小都有限制,通常是 4KB 左右,这限制了可以存储的信息量。
    如果一个网站尝试设置过多的 Cookie,可能会因为浏览器限制而失败。

  4. 性能影响:
    每次 HTTP 请求都会携带 Cookie,这可能会增加请求头的大小,从而影响网络传输的性能。
    如果网站使用了大量的 Cookie,或者 Cookie 的内容很大,这可能会显著降低页面的加载速度。

  5. 不跨域:
    Cookie 通常只能由设置它们的同一个域访问,这限制了跨域共享信息的能力。
    虽然有一些技术(如 CORS with credentials)可以实现跨域 Cookie 共享,但这增加了复杂性和潜在的安全风险。

  6. 用户可删除或禁用:
    用户可以随时删除他们计算机上的 Cookie,这可能导致网站功能失效或用户会话丢失。
    一些用户可能会禁用 Cookie,这可能会影响网站的正常运行。

  7. 不适用于所有设备:
    一些设备或浏览器可能不支持 Cookie,或者对 Cookie 的支持有限,这可能会影响网站在这些设备上的表现。


注意

  • 大小限制:每个 Cookie 的大小通常限制在 4KB 以内,且浏览器对单个域名下的 Cookie 数量也有限制。

  • 安全性:Cookie 中的敏感信息应该被加密,以防止被恶意用户窃取。同时,使用 HttpOnly 和 secure 属性可以增强 Cookie 的安全性。

  • 隐私:过多的 Cookie 可能会影响用户的隐私体验,因此应该尽量减少不必要的 Cookie 使用。


如何发送一个带有cookie的HTTP请求

在JavaScript中,发送带有Cookie的HTTP请求通常是通过浏览器自动处理的
默认情况下,如果浏览器的文档中存在 Cookie,并且这些 Cookie 对于请求的 URL 是有效的,那么浏览器会自动将这些Cookie附加到同源的Axios请求中,通常不需要额外的配置。

如果想从客户端手动设置 Cookie,或者在服务器端处理跨域请求时需要携带 Cookie,那么你需要确保满足以下几个条件:

  1. 跨域时服务器端设置:
    对于跨域请求,服务器端需要设置正确的 CORS 策略,允许携带 Cookie。

    这通常涉及设置 Access-Control-Allow-OriginAccess-Control-Allow-Credentials 等响应头。

    例如,在服务器端(以 Express.js 为例)你可能需要这样设置:

    res.header('Access-Control-Allow-Origin', 'https://example.com'); // 允许请求的源  
    res.header('Access-Control-Allow-Credentials', true); // 允许携带凭证(即 Cookie)
    
  2. 跨域时客户端设置:
    在 Axios 请求中,你需要设置 withCredentials 选项为 true。

    只有需要处理跨域请求时才需要设置 withCredentials。对于同源请求,浏览器默认会发送 Cookie。

    axios.defaults.withCredentials = true; // 全局设置  
    
    // 或者在单个请求中设置  
    axios.get('https://api.example.com/data', {  
      withCredentials: true  
    })  
    .then(response => {  
      // 处理响应  
    })  
    .catch(error => {  
      // 处理错误  
    });
    
  3. 手动设置请求头:
    虽然不推荐这样做,因为这样做可能会绕过浏览器的安全策略,但在某些情况下,你可能需要手动设置请求头来包含Cookie。这通常不是跨域请求的做法,因为浏览器会阻止这样做以维护安全性。

    axios.get('https://api.example.com/data', {  
      headers: {  
        Cookie: 'your=cookie; another=cookie' // 这里的值应该是你希望发送的Cookie字符串  
      }  
    })  
    .then(response => {  
      // 处理响应  
    })  
    .catch(error => {  
      // 处理错误  
    });
    
  4. Cookie 的设置:
    确保 Cookie 的 SameSiteSecure 属性设置正确,以避免由于浏览器的安全策略导致 Cookie 不被发送。

    • Secure:确保Cookie只能通过HTTPS协议传输,这有助于防止Cookie在不安全的网络中被截获。

    • Samesite:用来标明这个cookie是否是“同站cookie”。同站cookie只能在本域名中使用,不能作为第三方cookie, 限制第三方Cookie,从而帮助减少安全风险

确保你理解浏览器如何处理Cookie以及CORS策略,因为这涉及到安全性问题。不要在不了解这些机制的情况下尝试绕过浏览器的安全限制。在大多数情况下,让浏览器自动处理Cookie是最简单和最安全的方法。



session、cookie、webstorage的区别

session、cookie、webstorage的区别

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫老板的豆

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值