【问题标题】:Proxying of document.cookiedocument.cookie 的代理
【发布时间】:2015-12-01 08:04:56
【问题描述】:

我需要记录 document.cookie 的设置。我不能只用document.cookie = {...} 重新定义cookie 属性所以我需要为document.cookie 获取setter。但是Object.getOwnPropertyDescriptor(document, "cookie") 返回undefined

UPD。当我写这个问题时,我找到了一个可行的解决方案,但它使用了已弃用的 __lookupGetter____lookupSetter__ 方法。有没有不使用过时 API 的解决方案?

【问题讨论】:

    标签: javascript cookies proxy javascript-objects


    【解决方案1】:

    在我写问题时,我发现下一个代码解决了我的问题:

    var cookie_setter_orig = document.__lookupSetter__("cookie").bind(document);
    var cookie_getter_orig = document.__lookupGetter__("cookie").bind(document);
    Object.defineProperty(document, "cookie", {
      get: function () {
        return cookie_getter_orig();
      },
      set: function (val) {
        console.log(val);
        cookie_setter_orig(val);
      }
    });
    

    但我不喜欢使用过时的方法,所以希望有更好的解决方案。

    【讨论】:

      【解决方案2】:

      访问getter和setter的标准化方式是使用Object.getOwnPropertyDescriptor,但顾名思义,它只查找对象自身的属性(它不查找原型链)。 documentHTMLDocument 的一个实例,它继承自Document。在现代浏览器中,cookie 属性是在 Document.prototype 上定义的,而在旧版本的 Firefox 中,它是在 HTMLDocument.prototype 上定义的。

      var cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
                       Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
      if (cookieDesc && cookieDesc.configurable) {
          Object.defineProperty(document, 'cookie', {
              get: function () {
                  return cookieDesc.get.call(document);
              },
              set: function (val) {
                  console.log(val);
                  cookieDesc.set.call(document, val);
              }
          });
      }
      

      讽刺的是,在最关注隐私的浏览器Safari中,描述符已经将configurable设置为false,并且不包含getter和setter,__lookupGetter__或@也不包含987654333@。所以我还没有找到在 Safari 中覆盖 document.cookie 的方法(OS X 和 iOS 9.0.2 上的 8.0.8)。 WebKit nightly 的行为方式与 Safari 相同,因此它似乎不会很快得到修复。

      2019 年 10 月更新: 在 MacOS Mojave 上的 Safari 12.1.2 中测试了上述代码,cookieDesk 现在可以配置了!这意味着我从 2015 年开始的 proof of concept document.cookie protection 现在可能真的可以工作了 :)

      【讨论】:

      • Firefox 的新版本在Document 上定义了它,就像其他浏览器一样。仍应将评论保留在答案中,作为提示
      • @PatrickHollweck 感谢您的提醒!更新了答案以反映 Firefox 的变化。
      • 您好,感谢您分享此解决方案,它适用于许多 cookie,但并非适用于所有 cookie。例如,这个脚本设置的cookie“_fbp”:connect.facebook.net/signals/config/…似乎没有被这个解决方案覆盖。知道为什么吗?
      • @nikelone 您的链接错误,但我认为他们使用 iframe 来设置该 cookie,此处的方式仅适用于 window.top。将其添加到动态创建的 iframe 中仍然是可能的,但需要您做更多的原型覆盖......
      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多