正在删除Javascript Synchronous中的cookie

Is deleting a cookie in Javascript Synchronous?

本文关键字:中的 cookie Synchronous Javascript 删除      更新时间:2023-09-26

我或多或少有一个Javascript Delete Cookie Before Reload或Redirect的副本,但从未得到任何答案。

我继承了一些执行以下的javascript代码

 function delete_cookie ( cookie_name )
  {
     var cookie_date = new Date ( );  // current date & time
     cookie_date.setTime ( cookie_date.getTime() - 1 );
     document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
  }
  delete_cookie ( "sessionId" );
  window.location ="https://some_redirect";

问题是重定向页面的GET包含原始cookie(显然没有被删除),服务器只是不断地用删除/重定向代码(在chrome/canary/IE上测试)进行响应。如果有区别,cookie最初被设置为简单的"sessionId=;"

cookie始终设置为以下模式

"Set-Cookie: sessionId=%s;path=/;%s postId=%s;%s " "'r'n"

我知道toGMTString已被弃用,直接设置为window.location可能并不理想。这两者似乎都与问题无关。

如果我把window.location调用放在setTimeout中,或者如果我把它作为delete_cookie的回调执行,那么一切都会神奇地完美工作。但为什么呢?

似乎工作可靠

function delete_cookie (cookie_name, callback)
{ 
   ...
   callback();
 }
delete_cookie( "sessionID", doRedirect);

其中doRedirect只是window.location

这种行为是意料之中的吗?我的假设是,当cookie在过去设置了到期日时,它会在代码继续执行之前被删除。是否有更好的机制来确保cookie在重定向之前已被删除?

编辑:附加信息

如下修改cookie对没有帮助

       function delete_cookie ( cookie_name )
       {
+         var retries = 0;
          var cookie_date = new Date ( );  // current date & time
          cookie_date.setTime ( cookie_date.getTime() - 1 );
          document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
+      
+         while (document.cookie.indexOf("sessionId=") != -1)
+         {
+            retries +=1;
+            if (retries == 1000) 
+            { 
+                console.log("giving up after 1000 retries");
+                break;
+            }
+
+         }
+         console.log("We had to retry "+retries+" time(s)");
       }
       delete_cookie ( "sessionId" );

控制台输出为

重试1000次后放弃

我们不得不重试1000次

有趣的是,如果我在客户端上调试,我会看到以下

Canary(版本42.0.2302.2 Canary(64位))

javascript重定向代码从开发控制台的"资源"选项卡提供后,在Cookies->10.0.11.18下会显示"此网站没有cookie。"

但在单独的选项卡中chrome://settings/cookies我仍然可以看到

Name:   sessionId 
Content:     
Domain: 10.0.11.118 
Path:   / 
Send for:   Any kind of connection 
Accessible to script:   Yes 
Created:    Thursday, February 12, 2015 at 12:26:07 PM 
Expires:    When the browsing session ends

这与cookie无关,而是时间。

您所做的不是返回时间的,而是毫秒

因此,当你问它GMT时间格式时,在大多数情况下,它甚至不知道现在和一毫秒前的时间格式有什么区别。它将显示与一毫秒前相同的时间,并且cookie不会被删除,因为cookie尚未过期。

你想做的是走一千毫秒,也就是一秒钟,回到过去。

var cookie_date = new Date ( );
alert(cookie_date.toGMTString()); 
//outputs Sat, 14 Feb 2015 18:07:45 GMT
cookie_date.setTime ( cookie_date.getTime() - 1 );
alert(cookie_date.toGMTString()); 
//outputs Sat, 14 Feb 2015 18:07:45 GMT
var good_cookie_date = new Date ( );     
alert(good_cookie_date.toGMTString());
//outputs Sat, 14 Feb 2015 18:07:45 GMT
good_cookie_date.setTime ( good_cookie_date.getTime() - 1000 );
alert(good_cookie_date.toGMTString());
//outputs Sat, 14 Feb 2015 18:07:44 GMT

请参阅fiddle示例

我试图让这个答案尽可能通用,这是以下问题之一,要么是使用相同密钥的多个cookie,要么是您的问题是过期时间不够


cookie有几种可能不会被删除。

同一块饼干可以有多个

Cookies可以设置多个变量。通过使用不匹配的参数设置相同的cookie,您将创建服务器端框架可能无法处理的重复项,或者默认为发送到服务器的第一个或最后一个。


Cookie参数

域必须设置为当前域或父域。

路径

除了域层次结构之外,还有一个基本路径层次结构。默认值通常为"/",使cookie可用于域内的所有路径。

HTTP-ONLY标志

设置后,您将无法通过JavaScript修改所述cookie,如果是这种情况,您很可能会设置重复的cookie。

过期

这不会影响重复项,但如果设置为无效值,或者后面不够远的东西(同一秒)可能会被忽略,或者创建意外的cookie。


建议

  • 确认正在为有问题的cookie设置的域和路径
  • 使用固定的已知旧日期(new Date(0).toGMTString()),而不是从当前日期/时间进行调整
  • 请确保所设置的值为空,从null/undefined转换可能会导致意外的字符串
  • 使用location.replace('newurl')而不是分配location.href以避免任何潜在的缓存问题

在大多数情况下,以下内容应该会清除您的cookie。。。

document.cookie = 'YOURKEY=; expires=THU, 01 JAN 1970 00:00:00 GMT';

如果你需要清理一条路。。。

document.cookie = 'YOURKEY=; expires=THU, 01 JAN 1970 00:00:00 GMT; path=/';

旁白

一般来说,不要把你的cookie设置得太远。。。

谷歌浏览器

我在我的机器里试过你的代码。我设置了带有和不带有路径的cookie=/。在这两种情况下,它都运行良好。也就是说,代码首先删除cookie,然后重定向。

Firefox

我可以在firefox中重现这个问题。

正如你所说,在设置cookie时使用了path=/,我在取消设置时使用了相同的格式。

document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString() + "; path=/";

它工作了一次,然后再次显示问题。我可以将这个问题与缓存联系起来。因为当我将重定向行更新为时

window.location ="redirect.html?"+Math.random();

一切开始顺利进行。随机字符串避免缓存。