Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is deleting a cookie in Javascript Synchronous?

I have more or less a duplicate of Javascript Delete Cookie Before Reload or Redirect which never got any answers.

I inherited some javascript code that does the following

 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";

The problem is that the GET for the redirect page contains the original cookie (which apparently was not deleted), and the server just continually responds with the delete/redirect code (tested on chrome/canary/IE). If it makes a difference, the cookie was initially set to simply "sessionId=;"

The cookie is always set with the following pattern

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

I am aware that toGMTString is deprecated, and that setting directly to window.location is perhaps non-ideal. Neither of those seem related to the problem.

If I put the window.location call inside a setTimeout, or if I execute it as a callback from delete_cookie then everything magically works perfectly. But why?

This seems to work reliably

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

where doRedirect is just the window.location

Is this behavior expected? My presumption was that when the cookie was set with an expiry date in the past it would be deleted before code execution continued. Is there a better mechanism to ensure the cookie has been deleted prior to the redirection?

EDIT: Additional information

Modifying the cookie as follows doesn't help things

       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" );

Console output is

giving up after 1000 retries

We had to retry 1000 time(s)

Interestingly, if I am debugging on the client I see the following

Canary (Version 42.0.2302.2 canary (64-bit))

After the javascript redirect code is served up from the dev console "Resources" tab, under Cookies->10.0.11.118 it says "This site has no cookies."

But in a separate tab to chrome://settings/cookies I can still see

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
like image 586
Andrew C Avatar asked Feb 19 '26 07:02

Andrew C


2 Answers

This has nothing to do with your cookies, but time.

What you are doing is not going a second back in time but a millisecond.

So when you are asking it for a GMT time format, in most cases it won't even know the difference, between now and a millisecond ago in time format. It will show the same time as a millisecond ago and the cookie won't be deleted, because the cookie is not yet expired.

What you want to do is to go a thousand milliseconds, thus a second, going back in time.

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

See fiddle example

like image 111
Drifter Avatar answered Feb 21 '26 21:02

Drifter


I've tried to make this answer as generic as possible, one of the below issues, either with multiple cookies with the same key, or a not passed enough expiration is your issue


There are several possibilities for cookies not getting deleted.

You can have more than one of the same cookie

Cookies can be set with several variables. By setting the same cookie with parameters that do not match, you will create duplicates that your server-side framework may be unable to handle, or default to the first or last one sent to the server.


Cookie Parameters

Domain

The domain must be set to the current domain, or parent domain.

Path

In addition to a domain hierarchy, there is also a base-path hierarchy. The default is usually '/', making a cookie available to all paths within the domain.

HTTP-ONLY Flag

When set, you will not be able to modify said cookie via JavaScript, and you may well be setting a duplicate cookie if this is the case.

Expiration

This doesn't affect duplicates, but if set to an invalid value, or something that isn't far enough back (same second) may be disregarded or create an unexpected cookie.


Suggestions

  • Confirm the domain and path that are being set for the cookie in question.
  • Use a fixed, known to be old date (new Date(0).toGMTString()) instead of adjusting from the current date/time
  • ensure that your value being set is empty, conversion from null/undefined may result in an unexpected string.
  • use location.replace('newurl') instead of assigning the location.href to avoid any potential caching issues.

The following should clear your cookie under most circumstances...

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

If you need to clear a path...

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

Aside

In general, don't set your cookies too far into the future...

like image 31
Tracker1 Avatar answered Feb 21 '26 22:02

Tracker1