【问题标题】:Deleting cookie: how to get its path (and domain)?删除 cookie:如何获取其路径(和域)?
【发布时间】:2019-10-05 21:55:04
【问题描述】:

各种文章和SO answers建议通过JS删除cookie应该是这样的:

document.cookie = cookieName + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

或者如果我们需要指定域/路径,像这样:

document.cookie = cookieName + "=" +
    (path   ? `;path=${path}` : "") +
    (domain ? `;domain=${domain}` : "") +
    ";expires=Thu, 01 Jan 1970 00:00:01 GMT";

现在,在非根位置(如https://classic.tiddlywiki.com/upgrade/)发生了更复杂的情况。如果你打开它并在控制台输入document.cookie,你会得到一个值(没有指定domainpathexpires):

TiddlyWikiClassicOptions=chkRegExpSearch:%22false%22 chkCaseSensitiveSearch:%22false%22 chkIncrementalSearch:%22true%22 chkAnimate:%22true%22 chkSaveBackups:%22true%22 chkAutoSave:%22false%22 chkGenerateAnRssFeed:%22false%22 chkSaveEmptyTemplate:%22false%22 chkOpenInNewWindow:%22true%22 chkToggleLinks:%22false%22 chkHttpReadOnly:%22true%22 chkForceMinorUpdate:%22false%22 chkConfirmDelete:%22true%22 chkInsertTabs:%22false%22 chkUsePreForStorage:%22true%22 chkDisplayInstrumentation:%22false%22 chkRemoveExtraMarkers:%22false%22 txtBackupFolder:%22%22 txtEditorFocus:%22text%22 txtMainTab:%22Timeline%22 txtMoreTab:%22moreTabAll%22 txtMaxEditRows:%2230%22 txtFileSystemCharSet:%22UTF-8%22 txtTheme:%22%22 txtUserName:%22YourName%22

在控制台中写入

document.cookie = 'TiddlyWikiClassicOptions=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

不会删除 cookie(或更改其值)(document.cookie 给出相同的结果)。此外,写作

document.cookie = 'TiddlyWikiClassicOptions=lalala';

不会更改现有的 cookie,而是添加另一个具有相同名称的 cookie:

TiddlyWikiClassicOptions=lalala; TiddlyWikiClassicOptions=chkRegExpSearch:%22false%22 chkCaseSensitiveSearch:%22false%22 chkIncrementalSearch:%22true%22 chkAnimate:%22true%22 chkSaveBackups:%22true%22 chkAutoSave:%22false%22 chkGenerateAnRssFeed:%22false%22 chkSaveEmptyTemplate:%22false%22 chkOpenInNewWindow:%22true%22 chkToggleLinks:%22false%22 chkHttpReadOnly:%22true%22 chkForceMinorUpdate:%22false%22 chkConfirmDelete:%22true%22 chkInsertTabs:%22false%22 chkUsePreForStorage:%22true%22 chkDisplayInstrumentation:%22false%22 chkRemoveExtraMarkers:%22false%22 txtBackupFolder:%22%22 txtEditorFocus:%22text%22 txtMainTab:%22Timeline%22 txtMoreTab:%22moreTabAll%22 txtMaxEditRows:%2230%22 txtFileSystemCharSet:%22UTF-8%22 txtTheme:%22%22 txtUserName:%22YourName%22

这就是我在干净的 Chrome 中得到的。我也试过在 Vivaldi 中安装 HTML5 Storage Manager All in One(Chrome 扩展),它显示相同,除了存在 2 个 cookie 的情况:而控制台给出与上面相同的行(在document.cookie) , 扩展显示

https://classic.tiddlywiki.com/ 不会发生这种情况(删除/编辑按预期工作)。

现在,我认为要删除初始 cookie,我必须这样做

document.cookie = 'TiddlyWikiClassicOptions=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

如果我添加了lalala,我也必须这样做

document.cookie = 'TiddlyWikiClassicOptions=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

删除第二个。

我想知道,我如何确定应该使用哪条路径? document.cookie 似乎对每个 cookie 的“范围”保持沉默。或者这是设计引入的东西,我总是必须知道哪个 cookie 分配给哪个路径?

PS 我看到一篇帖子让我觉得域 (it's in Russian) 也存在同样的问题,所以我想知道如何让域也与 cookie 关联。

【问题讨论】:

    标签: javascript cookies


    【解决方案1】:

    如果您不知道 cookie 的(子)域和/或路径,请尝试使所有组合过期。

    var hostname = window.location.hostname;
    var pathname = window.location.pathname;
    var i = -1;
    do {
      var domain = hostname.substr(i+1);
      var j = 0;
      do {
        var path = pathname.substr(0,j+1);
        var cookie = 'TiddlyWikiClassicOptions=; path='+path+'; domain='+domain+'; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
        console.log(cookie);
        // stacksnippets throws an exception... uncomment to set cookie.
        //document.cookie = cookie;
      } while ((j = pathname.indexOf('/', j+1)) != -1)
    } while ((i = hostname.indexOf('.', i+1)) < hostname.lastIndexOf('.'));

    【讨论】:

    • 这是我将使用的合理方法;不过,我对实现不太满意(难以阅读和修改),所以我在下面添加了我的
    • 很高兴这个答案很有帮助。就编码风格而言,每个人都有自己的风格。我承认这有点脑筋急转弯。如果您询问 3 个开发人员,您可能会得到 4 个实现 :) 如果您真的想获得一些关于您的实现的反馈,您可以将其提交到 codereview.stackexchange.com?干杯。
    【解决方案2】:

    这是我对 dana 想法的实现(删除每个路径+域对的 cookie):

    function deleteCookieFromAllScopes(cookieName)
    {
        var domainParts = window.location.hostname.split('.').reverse();
        var topLevelDomain = domainParts.shift();
        var domains = [];
        for(let domainPart of domainParts)
        {
            let prevDomain = domains.slice(-1)[0] || topLevelDomain;
            domains.push(domainPart + '.' + prevDomain);
        }
    
        var path = window.location.pathname;
        var paths = ['/'], pathLength = 1, nextSlashPosition;
        while( (nextSlashPosition = path.indexOf('/', pathLength)) != -1 )
        {
            pathLength = nextSlashPosition + 1;
            paths.push(path.substr(0, pathLength));
        }
    
        for(let path of paths)
            for(let domain of domains)
                document.cookie = `${cookieName}=; path=${path}; domain=${domain}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
    }
    

    它不再是毫无疑问的,但我认为更具可读性。欢迎提出改进建议。

    以下是对通过file: 方案或localhost 域打开的页面的特殊cookie 情况的修改:

    function deleteCookieFromAllPaths(cookieName)
    {
        var path = window.location.pathname;
        var paths = ['/'], pathLength = 1, nextSlashPosition;
        while( (nextSlashPosition = path.indexOf('/', pathLength)) != -1 )
        {
            pathLength = nextSlashPosition + 1;
            paths.push(path.substr(0, pathLength));
        }
    
        for(let path of paths)
            document.cookie = `${cookieName}=; path=${path}; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      • 1970-01-01
      • 2017-10-19
      • 2015-12-11
      • 2016-04-28
      相关资源
      最近更新 更多