6

我手头的问题是我需要一个变量来跟踪我的所有cookie,以便我可以将该变量中的字符串拆分为一个数组,然后从那里解析字符串。我想知道为什么下面的简单代码不适合我?

var count = 0;          //keeps track of how many times this page has been visited
var lastVisit = new Date();     //records the last visit date in UTC format (or extra-challenge: in a user-friendly format like "Tuesday 10/12/2013 at 9:34:50")
var exDate  = new Date(lastVisit.getTime() + 30000);
var savedData = decodeURI(document.cookie);  //contains cookie contents

document.cookie = encodeURI("count=" + count.toString() + "; expires=" + exDate.toUTCString());

我需要发生的是,每当我为它设置一个 cookie 以将其添加到 savedData 变量时,我无法弄清楚为什么没有发生这种情况。谢谢

4

2 回答 2

11

你不应该编码'expires ='。它会变成'expires%3D',这不是你想要的。除此之外,使用“encodeURI”可能不是一个好主意,因为它不编码“;” 和“,”根据需要。

您可以使用 encodeURIComponent 对 cookie 值进行编码,但使用 escape() 对 cookie 值进行编码在技术上是正确的。

所以...

document.cookie = "count=" + encodeURIComponent(count.toString()) + "; expires=" + exDate.toUTCString();

...应该做你想做的。
cookie 由几个部分组成;我们最感兴趣的是名称、价值和到期日。

(官方回答结束)


让我们澄清一下编码cookie的困惑

如果有任何疑问,请联系 RFC,不要只选择您在 Web 上找到的任何似乎有效的东西。

cookie-name 的类型为token,这意味着其中只允许包含以下值:
0x21-0x270x2A-0x2B0x2D-0x2E0x30-0x390x41-0x5A0x5E-0x7A0x7E
换句话说:以下值应进行百分比编码:
0x00-0x20'('')'',''/'':'';' , '<' , '=' , '>' , '?' , ', '[' , ']' , '{' , '}'0x7F-0xFF

cookie-value 是cookie-octet类型,这意味着其中只允许以下值:
0x21、0x23-0x2B、0x2D-0x3A、0x3C-0x5B、0x5D-0x7E
换句话说:以下值应该是百分比编码的:
0x00-0x20 , 0x22 , ',' , ';' , ''0x7F-0xFF

现在,使用 toUTCString() 对到期日期进行编码,正如您所做的那样。
结果如下所示:Wed, 09 Jun 2021 10:18:14 GMT - 所以它将包含一个逗号。但!除了 cookie-name 和 cookie-value 字符串之外,您不应该对任何内容进行编码。

注意:W3Schools表示在 JavaScript 1.5 中不推荐使用 escape(),但在 cookie 中使用 encodeURI() 或 encodeURIComponent() 在技术上是不正确的。对 cookie 使用 escape() 在技术上是正确的。

RFC 6265 第 5.4 节明确指出:

注意:尽管它的名字,cookie-string 实际上是一个
八位字节序列,而不是一个字符序列。要将 cookie 字符串
(或其组件)转换为字符序列(例如,用于
呈现给用户),用户代理可能希望尝试使用
UTF-8 字符编码 [RFC3629] 来解码八位字节序列。
但是,此解码可能会失败,因为并非每个八位字节序列都是有效的 UTF-8。

由于 decodeURIComponent() 用于 unicode 字符串,并且会阻塞 0x00 和 0xFF 之间的字节值,因此不能安全地使用它们。另一方面, unescape()不是用于字符串,而是用于 8 位字节序列,也就是。octets,但前提是您的字节序列不包含 unicode 字符。

如果您的 cookie 值包含 unicode 字符,那么您应该使用 encodeURIComponent()/decodeURIComponent(),但您也应该捕获任何异常,因为服务器可能不会准确地向您发送您想要接收的内容。

于 2014-12-03T20:50:35.327 回答
1

大多数浏览器还支持btoaBase64 编码和 Base64atob解码。Base64 中的所有字符都是合法的 cookie 八位字节(当以 ASCII 或 UTF-8 解释时)。因此,您可以(以额外的存储空间为代价)将持久值的 Base64 编码存储为 cookie 值,在持久(和检索)该值时进行编码(和解码)。

于 2018-01-17T22:23:31.627 回答