cookie的使用

本文详细解析了Cookie的工作原理,包括其限制条件、属性、编码方式及兼容性问题。探讨了Cookie的大小限制、编码方法、属性设置以及如何通过JavaScript进行编码。同时,文章也提到了Cookie的自动删除机制和子Cookie的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

限制条件

cookie 存在许多限制条件,来阻止 cookie 滥用并保护浏览器和服务器免受一些负面影响。有两种 cookie 限制条件:cookie 的属性和 cookie 的总大小。原始规范中限定每个域名下不超过 20 个 cookie,早期的浏览器都遵循该规范,并且在 IE7 中有更近一步的提升。在微软的一次更新中,他们在 IE7 中增加 cookie 的限制数量到 50 个,与此同时 Opera 限定 cookie 数量为 30 个,Safari 和 Chrome 对与每个域名下的 cookie 个数没有限制。

发向服务器的所有 cookie 的最大数量(空间),也就是一次请求发送cookie的量,仍旧维持原始规范中所指出的:4KB。所有超出该限制的 cookie 都会被截掉并且不会发送至服务器。

编码

对于 cookie 的值进行编码一直都存在一些困惑。普遍认为 cookie 的值必须经过 URL 编码,但其实这是一个谬论,尽管通常都这么做。原始规范中明确指出只有三个字符必须进行编码:分号、逗号和空格,规范中还提到可以进行 URL 编码,但并不是必须,在 RFC 中没有提及任何编码。然而,几乎所有的实现都对 cookie 的值进行了一系列的 URL 编码。对于 name=value 格式,通常会对 name 和 value 分别进行编码,而不对等号 = 进行编码操作。

Javascript中提供了3对函数用来对Url编码以得到合法的Url,它们分别是
escape / unescape,
encodeURI / decodeURI
encodeURIComponent / decodeURIComponent。
兼容性不同:escape函数是从Javascript1.0的时候就存在了,其他两个函数是在Javascript1.5才引入的。但是由于Javascript1.5已经非常普及了,所以实际上使用encodeURI和encodeURIComponent并不会有什么兼容性问题。 
对Unicode字符的编码方式不同:这三个函数对于ASCII字符的编码方式相同,均是使用百分号+两位十六进制字符来表示。但是对于Unicode字符,escape的编码方式是%uxxxx,其中的xxxx是用来表示unicode字符的4位十六进制字符。这种方式已经被W3C废弃了。但是在ECMA-262标准中仍然保留着escape的这种编码语法。encodeURI和encodeURIComponent则使用UTF-8对非ASCII字符进行编码,然后再进行百分号编码。这是RFC推荐的。因此建议尽可能的使用这两个函数替代escape进行编码。
适用场合不同:encodeURI被用作对一个完整的URI进行编码,而encodeURIComponent被用作对URI的一个组件进行编码。从上面提到的安全字符范围表格来看,我们会发现,encodeURIComponent编码的字符范围要比encodeURI的大。我们上面提到过,保留字符一般是用来分隔URI组件(一个URI可以被切割成多个组件,参考预备知识一节)或者子组件(如URI中查询参数的分隔符),如:号用于分隔scheme和主机,?号用于分隔主机和路径。由于encodeURI操纵的对象是一个完整的的URI,这些字符在URI中本来就有特殊用途,因此这些保留字符不会被encodeURI编码,否则意义就变了。 
组件内部有自己的数据表示格式,但是这些数据内部不能包含有分隔组件的保留字符,否则就会导致整个URI中组件的分隔混乱。因此对于单个组件使用encodeURIComponent,需要编码的字符就更多了。 

js编码Java解码问题

 

客户端编码:

var str1="这里是要编码的字符串%……&包含特殊字符1234";

var str2=encodeURIComponent(encodeURIComponent(str1));

//此处使用两次encodeURIComponent编码,编码后str2以参数形式传输到服务端,然后用java解码

//java解码

String str1=request.getParamater("str2");

String str2=java.net.URLDecoder.decode(java.net.URLDecoder.decode(str1, "utf-8"),"utf-8");

//此处的str2与js编码前的字符串完全一致

System.out.println(str2);

在客户端对参数进行二次编码,可以有效的避开“提交多字节字符”的这个棘手问题。
因为第一次编码,你的参数内容便不带有多字节字符了,成了纯粹的 Ascii 字符串。(这里把编第一次的结果叫成 [STR_ENC1] 好了。[STR_ENC1] 是不带有多字节字符的)
再编一次后,提交,接收时容器自动解一次 (容器自动解的这一次,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到 [STR_ENC1])
然后,再在程序中实现一次 decodeURIComponent (Java中通常使用 java.net.URLDecoder(***, "UTF-8")) 就可以得到想提交的参数的原值。  
 

属性

除了name(名)和value(值),cookie还有以下一些可选属性,用来控制cookie的有效期,作用域,安全性等:

expires属性——时间要转成GMT形式 : toGMTString();
  指定了cookie的生存期,默认情况下cookie是暂时存在的,他们存储的值只在浏览器会话期间存在,当用户退出浏览器后这些值也会丢失,如果想让 cookie存在一段时间,就要为expires属性设置为未来的一个用毫秒数表示的过期日期或时间点,expires默认为设置的expires的当前时间。现在已经被max-age属性所取代,max-age用秒来设置cookie的生存期。

如果max-age属性为正数,则表示该cookie会在max-age秒之后自动失效。浏览器会将max-age为正数的cookie持久化,即 写到对应的cookie文件中。无论客户关闭了浏览器还是电脑,只要还在max-age秒之前,登录网站时该cookie仍然有效。

如果max-age为负数,则表示该cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该cookie即失效。max-age 为负数的Cookie,为临时性cookie,不会被持久化,不会被写到cookie文件中。cookie信息保存在浏览器内存中,因此关闭浏览器该 cookie就消失了。cookie默认的max-age值为-1。

‍如果max-age为0,则表示删除该cookie。cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除cookie的效果。失效的Cookie会被浏览器从cookie文件或者内存中删除。

如果不设置expires或者max-age这个cookie默认是Session的,也就是关闭浏览器该cookie就消失了。

这里要说明一下:Session的cookie在ie6下,如果用户实在网页上跳转打开页面或新开窗口(包括target="_blank",鼠标 右键新开窗口),都是在同一个Session内。如果用户新开浏览器程序或者说是进程再打开当前的页面就不是同一个Session。其他浏览器只要你 Session存在,还是同一个Session,cookie还能共享。在前段时间的项目中ie6下吃了很大一个亏。

domain属性
  domain属性可以使多个web服务器共享cookie。domain属性的默认值是创建cookie的网页所在服务器的主机名。不能将一个cookie的域设置成服务器所在的域之外的域。
  例如让位于a.sodao.com的服务器能够读取b.sodao.com设置的cookie值。如果b.sodao.com的页面创建的cookie把 它的path属性设置为"/",把domain属性设置成".sodao.com",那么所有位于b.sodao.com的网页和所有位于 a.sodao.com的网页,以及位于sodao.com域的其他服务器上的网页都可以访问这个cookie。

path属性
  它指定与cookie关联在一起的网页。在默认的情况下cookie会与创建它的网页,该网页处于同一目录下的网页以及与这个网页所在目录下的子目录下的网页关联,与domain一起作用cookie的访问范围。

secure属性——用于指定cookie需要通过安全Socket层连接传递;
  它是一个布尔值,指定在网络上如何传输cookie,默认是不安全的,通过一个普通的http连接传输;

HttpOnly属性——用于避免cookie被Javascript访问;
  HttpOnly 属性限制了 cookie 对 HTTP 请求的作用范围。特别的,该属性指示用户代理忽略那些通过"非 HTTP" 方式对 cookie 的访问(比如浏览器暴露给js的接口)。注意 HttpOnly 属性和 Secure 属性相互独立:一个 cookie 既可以是 HttpOnly 的也可以有 Secure 属性。

同名cookie

同名的 cookie,不同的 domain 或不同的 path,属不同的 cookie;同名的 cookie,相同的 domain 且相同的 path,不同的 expires,属同一个 cookie。

cookie的自动删除

  • 会话 cooke (Session cookie) 在会话结束时(浏览器关闭)会被删除
  • 持久化 cookie(Persistent cookie)在到达失效日期时会被删除
  • 如果浏览器中的 cookie 数量达到限制,那么 cookie 会被删除以为新建的 cookie 创建空间。

子cookie

鉴于 cookie 的数量存在限制,开发者提出 subcookies 的观点来增加 cookie 的存储量。Subcookies 是存储在一个 cookie 值中的一些 name-value 对,通常与以下格式类似:

name=a=b&c=d&e=f&g=h

这种方式允许在单个 cookie 中保存多个 name-value 对,而不会超出浏览器 cookie 数量的限制。通过这种方式创建 cookie 的负面影响是,需要自定义解析方式来提取这些值,相比较而言 cookie 的格式会更为简单。服务器端框架已开始支持 subcookies 的存储。我编写的 YUI Cookie utility,支持在 javascript 中读/写 subcookies

参考:

https://blog.youkuaiyun.com/helloliuhai/article/details/18351439

https://www.kancloud.cn/kancloud/http-cookies-explained/48320

https://blog.youkuaiyun.com/lybwwp/article/details/16864495 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值