Javascript Cookie 设置两次;如何删除重复项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5621775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:06:11  来源:igfitidea点击:

Cookie is set twice; how to remove the duplicate?

javascriptcookies

提问by aroth

So I have a website that uses a cookie to remember the current layout state across visits. Everything was working great until I added a Facebook 'Like' button to the site which generates links that allow users to share a certain UI state (a little confusing but not really relevant to the problem).

所以我有一个网站,它使用 cookie 来记住访问中的当前布局状态。一切都很好,直到我在网站上添加了一个 Facebook 的“喜欢”按钮,该按钮会生成允许用户共享特定 UI 状态的链接(有点令人困惑,但与问题并不真正相关)。

The problem is that when I visit the site via one of these Facebook links a second copy of my layout cookie seems to be created (as in, I see two cookies with the same name and different values). This wouldn't be too terrible except that the value of the duplicate cookie appears to be stuck, coupled with the fact that when the user returns to the site the browser remembers the stuck value instead of the most recently set value (so it's kind of like there's a "good" cookie that I can still work with, and a "bad" one which I cannot, and the browser likes to remember the "bad" cookie instead of the "good" cookie). This breaks my layout tracking/remembering functionality.

问题是,当我通过这些 Facebook 链接之一访问该站点时,似乎创建了我的布局 cookie 的第二个副本(例如,我看到两个具有相同名称和不同值的 cookie)。这不会太糟糕,只是重复 cookie 的值似乎被卡住了,再加上当用户返回站点时,浏览器记住卡住的值而不是最近设置的值(所以它有点像就像有一个我仍然可以使用的“好”cookie 和一个我不能使用的“坏”cookie,并且浏览器喜欢记住“坏”cookie 而不是“好”cookie)。这打破了我的布局跟踪/记忆功能。

So there are two questions here:

所以这里有两个问题:

  1. How do I stop this from happening/why is this happening in the first place?
  2. How do I fix things for any users that already have a stuck cookie (I know I could just pick a new name for the cookie, but I'd rather do it by finding a way to properly unstick the stuck cookie)?
  1. 我如何阻止这种情况发生/首先为什么会发生这种情况?
  2. 我如何为已经卡住 cookie 的任何用户修复问题(我知道我可以为 cookie 选择一个新名称,但我宁愿通过找到一种正确解开卡住的 cookie 的方法来做到这一点)?

If I use Chrome's developer console after visiting the page in a stuck state, I can see that document.cookieis (formatting added for readability):

如果我在访问处于卡住状态的页面后使用 Chrome 的开发者控制台,我可以看到document.cookie(为了可读性添加了格式):

layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':1000000,'url':'http://m.xkcd.com/303/'}]; 
WibiyaNotification1=1; 
WibiyaNotification213286=213286; 
WibiyaNotification213289=213289; wibiya756904_unique_user=1; 
JSESSIONID=DONTHIHymanMEPLEASE; 
WibiyaProfile={"toolbar":{"stat":"Max"},"apps":{"openApps":{}},"connectUserNetworks":[null,null,null,null,null,null]}; 
WibiyaLoads=59; 
layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':6,'url':'http://m.xkcd.com/303/'}]"

Ignore the Wibiya cookies and the JSESSIONID. The stuck cookie is the first 'layoutState' instance, and the one that I can still manipulate in JavaScript is the second 'layoutState' instance. Here is what I get if I change some things around:

忽略 Wibiya cookie 和 JSESSIONID。卡住的 cookie 是第一个 'layoutState' 实例,而我仍然可以在 JavaScript 中操作的是第二个 'layoutState' 实例。如果我改变一些事情,我会得到以下结果:

layoutState=[{'id':6,'x':8,'y':1525,'z':4,'url':'undefined'}, {'id':1,'x':625,'y':709,'z':2,'url':'undefined'}, {'id':2,'x':8,'y':37,'z':3,'url':'undefined'}, {'id':3,'x':625,'y':1179,'z':5,'url':'undefined'}, {'id':4,'x':626,'y':37,'z':1,'url':'undefined'}, {'id':5,'x':626,'y':357,'z':1000000,'url':'http://m.xkcd.com/303/'}]; 
WibiyaNotification1=1;
WibiyaNotification213286=213286; 
WibiyaNotification213289=213289; 
wibiya756904_unique_user=1; 
JSESSIONID=DONTHIHymanMEPLEASE; 
WibiyaProfile={"toolbar":{"stat":"Max"},"apps":{"openApps":{}},"connectUserNetworks":[null,null,null,null,null,null]}; 
WibiyaLoads=59; 
layoutState=[{'id':1,'x':8,'y':39,'z':1000000,'url':'undefined'}]

The second 'layoutState' has the correct information that I want the browser to remember. However what the browser actually remembers is the value of the first instance.

第二个“layoutState”具有我希望浏览器记住的正确信息。然而浏览器真正记住的是第一个实例的值。

I've tried unsetting the cookie entirely, which causes the second instance to disappear, but nothing I do seems to get rid of the first instance. I get the same behavior in all major browsers (Chrome, Firefox, IE), which makes me suspect that I must be doing something fundamentally wrong here, but I'm not sure what it is.

我已经尝试完全取消设置 cookie,这导致第二个实例消失,但我所做的似乎没有摆脱第一个实例。我在所有主要浏览器(Chrome、Firefox、IE)中都有相同的行为,这让我怀疑我在这里做的事情肯定是根本错误的,但我不确定它是什么。

You can view the site itself here. Or click hereto access it via a Facebook link (should generate a stuck cookie). Any help is much appreciated.

您可以在此处查看站点本身。或单击此处通过 Facebook 链接访问它(应该会生成一个卡住的 cookie)。任何帮助深表感谢。

Update:

更新:

So the steps to reliably reproduce the error are as follows:

因此,可靠地重现错误的步骤如下:

  1. Visit the site via the Facebook-style link
  2. Make some changes to the layout, and then close the tab.
  3. Visit the site via the normal URL.
  4. Your layout from the initial visit should be correctly remembered, so change some things around and then refresh the page. When the page reloads, your changes will no longer be remembered.
  1. 通过Facebook 风格的链接访问该网站
  2. 对布局进行一些更改,然后关闭选项卡。
  3. 通过普通 URL访问该站点。
  4. 您应该正确记住初次访问时的布局,因此更改一些内容,然后刷新页面。当页面重新加载时,您的更改将不再被记住。

I've also noticed that revisiting the site via the Facebook-style URL is able to clear/reset the stuck cookie. So it's like the browser is keeping a separate cookie for each URL path, or something, and not allowing the root page to access the cookie that was set on the other URL path. I thought I might be able to fix this by explicitly setting path=/on the cookie, but no dice.

我还注意到,通过 Facebook 风格的 URL 重新访问该网站能够清除/重置卡住的 cookie。所以这就像浏览器为每个 URL 路径或其他东西保留一个单独的 cookie,并且不允许根页面访问在另一个 URL 路径上设置的 cookie。我想我可以通过path=/在 cookie 上显式设置来解决这个问题,但没有骰子。

Update 2:

更新 2:

I've found that if I set both the path and the domain of the cookie I get different behavior in all browsers:

我发现如果我同时设置 cookie 的路径和域,我会在所有浏览器中得到不同的行为:

  1. Firefox - Works correctly now, hooray!Worked correctly once, then broke, boo!
  2. Chrome - No change
  3. IE - Seems to be keeping separate cookies for each URL, so the Facebook-style URL remembers one state, and the standard URL remembers a different state. Both update correctly and independently of each other. This is kind of funky, but still way better than the stuck/broken state.
  1. Firefox -现在可以正常工作了,万岁!一次正常工作,然后坏了,嘘!
  2. 铬 - 没有变化
  3. IE - 似乎为每个 URL 保留单独的 cookie,因此 Facebook 样式的 URL 记住一种状态,而标准 URL 记住不同的状态。两者都正确且相互独立地更新。这有点时髦,但仍然比卡住/损坏状态好得多。

回答by syockit

Dude(tte), there are inconsistencies, and a bug, in your cookie setter.

伙计(tte),您的 cookie 设置器中存在不一致和错误。

1. Make sure path and domain is correctly set

1.确保路径和域设置正确

The path and domain should be the same for both clearing the cookie and setting it. See your code here:

清除cookie和设置cookie的路径和域应该相同。在此处查看您的代码:

document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";

and compare it to:

并将其与:

var c_value=escape(value) + "; expires=" + exdate.toUTCString(); + "; path=/spring; domain=aroth.no-ip.org";

you will see that the setter has both of them, but the deleter doesn't. You will bring about chaos.

你会看到 setter 有它们,但 deleter 没有。你会带来混乱。

2. Oh, and that nasty semicolon

2. 哦,还有那个讨厌的分号

That second line of code I quoted above, has a semicolon introduced in the middle of a string concatenation expression. Right after exdate.toUTCString(). Kill it. Kill it…now.

我上面引用的第二行代码在字符串连接表达式的中间引入了一个分号。紧随其后exdate.toUTCString()。杀了它。杀了它……现在。

At least on my Google Chrome, I managed to get it run correctly, if I set a breakpoint at json = "[" + json + "]";and modify setCookiebefore it is executed.

至少在我的谷歌浏览器上,如果我在它执行之前设置断点json = "[" + json + "]";并修改setCookie它,我设法让它正确运行。

P/S: It was a bizzare debugging experience, where I managed to set 4 layoutStatecookies, by fiddling with path & domain.

P/S:这是一次奇怪的调试体验,我layoutState通过摆弄路径和域设法设置了 4 个cookie。

回答by boisvert

This may be too simple, but just in case, are the cookies recorded for two different paths? If the URL is different, you may be setting your cookies for a restricted path, so the system would take them differently.

这可能太简单了,但以防万一,cookie 是否记录在两个不同的路径上?如果 URL 不同,则您可能将 cookie 设置为受限路径,因此系统会采用不同的方式。

回答by Scherbius.com

check in Chrome console -> Resourcesif your page gets loaded twice. That would be the reason of double cookie.

检查Chrome console -> Resources您的页面是否被加载两次。这就是双曲奇饼的原因。

回答by vusan

There is again the problem left after identifying the problem and taking prevention by correctly setting the cookie.
You also need to delete previous incorrectly set cookies in your or in your client's browser.

在确定问题并通过正确设置 cookie 采取预防措施后,问题再次出现。
您还需要删除之前在您或您客户的浏览器中错误设置的 cookie。

So observe the cookie set from developer tools and search for path and subdomain and put those explicitly on your code to delete.

因此,观察来自开发人员工具的 cookie 集并搜索路径和子域,并将它们明确地放在您的代码中以进行删除。

function eraseCookie(c_name) {
   document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";  

}

function eraseCookieWithPathDomain(c_name) {
       document.cookie = c_name + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;path=/yourpath/to; domain=sub.domain.com";
       //you can remove this function call on your second upload if you are confirm that the previous cookie setter expired
}

You may need to call function eraseCookieWithPathDomainright after eraseCookieor even every time after document load depending in your application.

根据您的应用程序,您可能需要在文档加载eraseCookieWithPathDomain之后eraseCookie甚至每次都调用函数。

回答by mike

Here is a solution, the / slash help to do not set duplicate cookie of same name

这是一个解决方案,/斜线帮助不要设置重复的同名cookie

setcookie('YourCookieName','yes', time() + 400, '/');

回答by Diodeus - James MacFarlane

It seems the issue is not a duplicate cookie (cookies overwrite themselves) but a duplication of the DATA in your cookie.

问题似乎不是重复的 cookie(cookie 会覆盖自己),而是 cookie 中的数据重复。

I think you'll have to modify the script that reads the cookie and clean out the duplicate value if it's detected.

我认为您必须修改读取 cookie 的脚本,并在检测到重复值时清除重复值。