我有这个奇怪的问题,我无法弄清楚,所以我希望比我聪明的人可以帮忙!
我有一个网站https://example.com
(没有子域名)
我有一些设置Cookie的代码,例如
var value="some value";
document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com";
此代码在某些脚本标记的页面加载期间运行。首次加载页面时,我会看到我的cookie集,并在(chrome)dev工具>申请>域列,我看到它在.example.com
上设置了一个前导点,这很好。
然后我刷新页面,我的代码再次运行(并且有一个新值被推送到cookie; dunno,如果这很重要)。我查看了应用程序选项卡,现在我看到了一个"重复的" myCookie
的条目 - .example.com
上的一个和example.com
上的另一个(无前导点)。值是相同的。 这对我来说很奇怪,我不知道为什么会这样。有没有人为什么会出现这种情况?
继续沿着这个兔子洞......我再次刷新页面,myCookie
上的.example.com
值更新,但example.com
上的值不更新。更奇怪!
与此同时,我还有其他尝试读取cookie的代码,但显然myCookie
上的example.com
cookie优先,我得到的值不是最新值(反映在{{1} }} 曲奇饼)。
我已尝试在.example.com
(.example.com
)上明确设置Cookie,但上述行为仍然会发生。另外,据我所知,javascript中没有办法明确引用domain=.example.com
上的cookie - .example.com
只显示document.cookie
一个(但开发工具应用程序选项卡确实如此)显示它?所以是这在javascript中公开了吗?)
我无法提供该网站的链接,但我可以尝试回答有人可能需要澄清的任何问题。
但我的主要问题是:任何人都可以解释这可能发生的原因,或者至少提供一些可能指向正确方向的东西吗?或者失败了,或者一些解决方法明确地从example.com
读取?
修改
此时,我最好的猜测是网站上的其他,可能是服务器端脚本,正在将Cookie从.example.com
复制到.example.com
但仅限于价值观发生了变化但这是纯粹的猜测。我还没有能够找到任何客户端证明(但是......)而且我实际上无法访问服务器端的东西。而且无论如何这可能都在吸管。但它是我最好的工作理论ATM,回到网站开发人员询问他们......
更新 - 我找到的新内容/澄清
要明确/重申:我的网站位于example.com
,否子域名。
这似乎只发生在我的cookie中,其中值会更改每个页面加载。值不变的Cookie似乎不会从https://example.com
推送到.example.com
。
即使对于具有动态值的Cookie,它似乎也只是{em} {em>} example.com
{em} 时间。.example.com
之后,example.com
Cookie值在后续页面加载时不会更改,即使example.com
版本获得新的动态值。
我创建了一个测试脚本,与我目前观察到这种行为的cookie分开,以便分而治之。我想用尽可能多的设置/读取cookie和blackbox的代码来排除任何恶作剧。
但我看到了同样的行为。我仍然怀疑这是某种服务器wtfery正在进行,例如.example.com
cookie将在下一个http请求中发送,然后服务器将它们写回.example.com
..仅在第一次?这是双重情节扭曲。我无法访问服务器端的东西,但我甚至不知道从哪里开始在网站开发人员看到什么。
另请注意,到目前为止,在我和我的同事之间,我们测试了设置问题Cookie的javascript lib /代码,以及其他6个网站上的blackbox脚本(甚至不属于/附属于此问题网站所有)并且不能够重现这个问题,这进一步让我们怀疑它是某种服务器配置问题(但同样,我们真的不知道从哪里开始那个)。
无论如何,如果它以某种方式帮助任何人,下面是我写的脚本(进一步)测试这个问题。我正在测试总共8个cookie:
example.com
设置为静态值domain=example.com
动态值domain=example.com
设置为静态值domain=.example.com
动态值domain=.example.com
domain=
domain=
指定为无值 domain=
domain=
- 这些最初设置在#1, #3
上,并且在页面刷新时不会被.example.com
欺骗
example.com
- 这些最初设置在#2, #4
上。在首页刷新时,原始值将被设置为.example.com
cookie / domain。在第二次+页面刷新时,example.com
cookie值不会更改(保留原始值),example.com
版本会在每个页面加载时获得新值。
.example.com
- 这些最初设置在#5, #7
(不是example.com
)上,.example.com
上永远不会有版本。
.example.com
- 这些最初设置在#6, #8
(不是example.com
)上,其值会更新每个页面加载,.example.com
上永远不会有版本。
测试代码
.example.com
基于提供的评论/答案的另一个更新
要明确的是,在实践中,问题是我们在页面加载时使用值设置了一些cookie。然后,当页面刷新(或在网站上导航到另一个页面)时,我们读取值,对其执行某些操作,生成新值并再次设置cookie。每次重复加载洗涤漂洗重复。
问题出在初始页面查看,这些Cookie是在var s_testCookies = {
getCookieValue: function(a) {
var b = document.cookie.match('(^|;)\\s*' + a + '\\s*=\\s*([^;]+)');
return b ? unescape(b.pop()) : '';
},
getRandomValue: function() {
return '' + (new Date()).getTime() + '|' + Math.floor(Math.random() * 100000);
},
run: function(data) {
var data = data || {};
console.log('------------------------');
console.log('Arg: ', JSON.parse(JSON.stringify(data)));
data.previousValue = s_testCookies.getCookieValue(data.name);
console.log('Previous: ', JSON.parse(JSON.stringify(data)));
data.cookie = data.name + "=" + escape(data.value) + "; path=/;";
data.cookie+= (typeof data.domain!='undefined') && (" domain="+data.domain+";") || "";
document.cookie = data.cookie;
data.newValue = s_testCookies.getCookieValue(data.name);
console.log('New: ', JSON.parse(JSON.stringify(data)));
console.log('------------------------');
}
} // end testCookies
s_testCookies.run({
'message': 'no dot static value',
'domain': 'example.com',
'name': 'test_no_dot_static',
'value': 'no dot static value'
});
s_testCookies.run({
'message': 'no dot dynamic value',
'domain': 'example.com',
'name': 'test_no_dot_dynamic',
'value': s_testCookies.getRandomValue()
});
s_testCookies.run({
'message': 'dot static value',
'domain': '.example.com',
'name': 'test_dot_static',
'value': 'dot static value'
});
s_testCookies.run({
'message': 'dot dynamic value',
'domain': '.example.com',
'name': 'test_dot_dynamic',
'value': s_testCookies.getRandomValue()
});
s_testCookies.run({
'message': 'implicit no domain static value',
'name': 'test_implicit_no_domain_static',
'value': 'implicit no domain static value'
});
s_testCookies.run({
'message': 'implicit no domain dynamic value',
'name': 'test_implicit_no_domain_dynamic',
'value': s_testCookies.getRandomValue()
});
s_testCookies.run({
'message': 'explicit no domain static value',
'domain':'',
'name': 'test_explicit_no_domain_static',
'value': 'explicit no domain static value'
});
s_testCookies.run({
'message': 'explicit no domain dynamic value',
'domain':'',
'name': 'test_explicit_no_domain_dynamic',
'value': s_testCookies.getRandomValue()
});
域上设置的。然后在下一页加载时,初始cookie /值将被设置为.example.com
,并且exampe.com
上的cookie也会获得更新的值。然后在另一个页面加载时,之前的.example.com
值不会被加载/推送到cookie的.example.com
版本;只有example.com
版本更新。所以它只会在第二页加载时被加载/推送到.example.com
。不是第3 +。
同时,example.com
cookie优先,并且是我们解析cookie值时返回的example.com
。因此,在第3页+页面加载时,我们只是继续获取从document.cookie
Cookie返回的第2页的值,而不是example.com
中的更新值
同时,我们不能简单地指定.example.com
值(domain=
以上),因为事实上存在子域名,例如#6 or #8
也有读取/更新/写入这些Cookie的代码,如果我们没有指定域名,那么该Cookie只能在mobile.example.com
上使用,并且无法在{{1}上读取}。
UDPATE
@ffeast 提出以下问题:
curl -I yourdomain返回什么?是否有任何Set-Cookie标头?
你走了!
example.com
我也从浏览器标签看到相同的响应标头。
所以在最初的http响应中有一些set-cookie标头,是的。它们不是我亲自与我的事物范围有任何关系的饼干,但我可以问它们的用途,如果它有所帮助。示例:
我注意到没有为它们显式设置mobile.example.com
值。这有可能以某种方式为浏览器设置先例,还是我咆哮错误的树?即使它确实如此,我也不认为这只能解释user@host:~$ curl -I https://example.com
HTTP/1.1 200 OK
X-Powered-By: Express
set-cookie: site#lang=en; Path=/;Secure
set-cookie: connect.sid=s%3As46fwOPaosGdwis0G_Wdv7gzUs75Q0rr.O1gLsLmrHmmdBXxPWJrIq8UWwOOaQf96qxUlW%2FxnEuM; Path=/; HttpOnly;Secure
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Content-Type: text/html; charset=utf-8
Content-Length: 19632
ETag: W/"4cb0-bgHMEy79PzLMv7jhB1Lh6A"
Vary: Accept-Encoding
Date: Fri, 16 Mar 2018 20:42:19 GMT
Connection: keep-alive
Set-Cookie: SecureCookie=!zPdIdxiz3mOMe2MYzy1p873u0yWtMdduASsHoU06gkaLs306mhR7cb3ir4TA2EG2cQGKmeVWJeYvxA/flQfPQUixqL8WMOfROsTgu3UZZg==; path=/; Httponly; Secure
对我改变价值的饼干,也不仅仅发生在第二页加载(而不是第三次+)?不确定你要去哪里,但我全都耳朵!
答案 0 :(得分:0)
如果您的目标是在所有子域之间使用cookie共享,允许每个人访问并设置cookie,那么您需要在设置cookie时指定根域。
假设您有sub.example.com
,sub2.example.com
和example.com
,并且您希望在他们之间共享Cookie,然后将域设置为example.com
。如果您未指定域名,则Cookie只是example.com
或sub.example.com
的属性,但当您将域指定为example.com
时,{{1}可以访问该域和它所有的子域来读写。
域 =域名(例如,' example.com'或' subdomain.example.com')。
如果未指定,则默认为当前文档的主机部分 位置(但不包括子域)。与之前相反 规范,域名中的前导点被忽略,但浏览器 可能拒绝设置包含此类点的cookie。如果域名是 指定的子域名始终包含在内 [来源:developer.mozilla.org]
在example.com中:
example.com
在sub.example.com中:(与上述相同)
var value="some value";
document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com";
在这两种情况下,您都必须将其设置为var value="some value";
document.cookie="myCookie="+escape(value)+"; path=/; domain=example.com";
。否则可能会出现以下情况
example.com
中,如果您忘记在同一个地方设置example.com
,则只会为example.com
创建一个与共享Cookie不同的新Cookie,并且不会与之同步它造成了很多混乱。example.com
中,如果您忘记在同一个地方设置sub.example.com
,则只会为example.com
创建一个与共享Cookie不同的新Cookie,并且不会与之同步它造成了很多混乱。sub.example.com
,因为根据上述报价不予理解。Cookie重复的可能原因:
.example.com
设置domain=example.com
的cookie,当第二个请求发出时,浏览器将cookie发送到服务器,服务器上的一些代码接收新cookie的一方将其设置回.example.com
。这只能通过检查第二个请求的响应头来验证。example.com
,以设置domain=example.com
的Cookie。当页面加载秒时间时,任何JavaScript代码都会错误地设置它而不指定为.example.com
设置cookie的domain=example.com
。只有在检查设置cookie所涉及的JavaScript代码时才能验证这一点。我认为意外创建域/子域特定cookie是您描述的所有异常的原因。查看正在设置cookie的每个代码部分都可以解决问题。
更新:这里发生了什么。
您正在使用 InvocaJS v3.6.6 和 AngularJS v1.2.19 ,它们都具有Cookie管理功能。 InvocaJS将数据存储在Cookie中example.com
并指定域invoca_session
,因此Cookie设置为example.com
。 AngularJS第一次看到cookie时没有问题,它会记住它。 AngularJS保留所有cookie的副本,当您通过AngularJS更新任何cookie时,您实际上会修改该副本。然后,AngularJS遍历所有cookie,将其与副本进行比较,以确定和更新AngularJS已更新的cookie。
InvocaJS反复更改.example.com
的值。当AngularJS循环遍历所有cookie并且invoca_session
与AngularJS的值不匹配时,它认为该值已被AngularJS更改(如上所述)并且它更新invoca_session
的值替换新的旧的价值。 (我测试了它,这正是AngularJS v1.2.19的工作原理)
问题是Angular v1.2.19在设置cookie时没有指定任何域(之前预测为错误概率#2)。因此,创建一个域名设置为invoca_session
的新cookie。之后,当InvocaJS尝试读取cookie时,它会读取为example.com
设置的旧cookie。
AngularJS更改Cookie
注1:你不明白答案并不总是意味着谁回答了解你的问题。如果你合作一点,你可以在7天前得到这个答案。
注2:你的黑匣子真的不能证明或反驳我提到的任何可能性。
注3:如果您现在合作,如果您不想丢弃或升级AngularJS,我可以提供进一步帮助。
答案 1 :(得分:-1)
根据w3schools.com documention,您可以使用函数来构建,获取和检查您的cookie。
您可以查看How do browser cookie domains work,here和here,以便更好地了解浏览器和javascript如何处理Cookie设置。
正如您在问题中所说的那样,Firefox也可以看到错误,可能需要注意:
与早期的规范相反,域名中的前导点会被忽略,但浏览器可能拒绝设置包含此类点的Cookie。如果指定了域,则始终包含子域。
正如你所说:
同时,example.com cookie优先,是我们解析cookie值时返回的一个document.cookie。因此,在第3页+页面加载时,我们只是继续获取从example.com cookie返回的第2页的值,而不是.example.com中的更新值
您可以仔细检查是否在第一次加载和将来的页面加载时从子域xxx.example.com加载了某些数据。
验证在将来重新加载期间是否缓存了某些数据。
您最终可能会仔细检查请求中是否存在以下标题:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
避免缓存问题。