【问题标题】:Retrieving document.cookie getter and setter检索 document.cookie 的 getter 和 setter
【发布时间】:2015-08-21 12:09:03
【问题描述】:

我正在尝试覆盖 document.cookie,因为我需要控制 cookie 创建,但似乎在 document.cookie 上的 getOwnPropertyDescriptor 没有检索到它的 getter 和 setter(在 chrome 和 firefox 上尝试过)。有人可以解释一下这种行为吗?

https://jsfiddle.net/1363ktwp/7/

var obj={};

// creating a property using document.cookie descriptors
Object.defineProperty(
    obj, 
    "oldCookie",   
    Object.getOwnPropertyDescriptor(document, "cookie")
);
    
// setting cookies succesfully
document.cookie="test1=ok;path=/;expires=365;";
document.cookie="test2=ok;path=/;expires=365;";

alert(document.cookie);

Object.defineProperty(document, "cookie", {
    get: function () {
        return obj.oldCookie;
    },
    set: function (cookie) {
        /*
            ...preliminar operations
        */
        
        obj.oldCookie = cookie;
    }
});
    
// obj.oldCookie is just a string without getter/setter
// so assignments below doesn't works correctly
document.cookie="test3=ok;path=/;expires=365;";
document.cookie="test4=ok;path=/;expires=365;";

alert(document.cookie);

【问题讨论】:

    标签: javascript cookies browser


    【解决方案1】:

    有人可以解释一下这种行为吗?

    document.cookiehost object 的属性。宿主对象通常不是真正的 JavaScript 对象(称为native objects),既不需要也不保证具有 JavaScript 对象的特性。

    事实上,如果许多甚至不止一两个浏览器使用 ES5 属性 getter/setter 实现 document.cookie,我会感到非常震惊。也许对于一些较新的 API(或者可能不是),但对于那么旧的 API,将会有很多麻烦。 (我还需要考虑很长一段时间来考虑安全后果......)

    如果他们确实通过 ES5 getter/setter 实现了它,那么如果他们将它设置为 不可配置 属性(例如,这样你可以'不要改变它)。

    【讨论】:

    • 感谢您的解释!我正在尝试解决欧盟 cookie 法产生的问题。它需要控制站点生成的所有类型的 cookie,但是如果不修改创建它的特定代码,就无法禁用/控制它们(在您拥有一个由不应该的 3rd 方插件填充的平台的上下文中)修改它变得非常困难)。这就是我寻找“全球”解决方案的原因。
    • @Joseph:是的。据我所知(我不是律师 [即使我是,我也不是你的律师]),关于这方面的最新指导是拥有 cookie 政策和指向从登录页面获取它可能就足够了,再加上一个简单的通知横幅(用户可以忽略它——有趣的是,您可以将首选项存储在 cookie 中,但最好存储在 localStorage 中)就足够了。更多:econsultancy.com/blog/…
    【解决方案2】:

    您可以使用__lookupSetter____lookupGetter__ 方法,但请注意它们已被弃用且并非所有地方都支持。它们在 Chrome、Firefox、IE11 中正常工作。不要在 IEundefined。没有检查其他任何东西。

    这是一个例子:

    var cookieSetterOrig = document.__lookupSetter__("cookie");
    var cookieGetterOrig = document.__lookupGetter__("cookie");
    Object.defineProperty(document, "cookie", {
        get: function () {
            return cookieGetterOrig.apply(document);
        },
        set: function () {
            return cookieSetterOrig.apply(document, arguments);
        },
        configurable: true
    });
    

    【讨论】:

      【解决方案3】:

      原因

      Object.getOwnPropertyDescriptor(document, 'cookie');
      

      返回 undefinedgetOwnPropertyDescriptor 的工作方式:它不遍历原型链。

      全局变量 document 包含实际继承自 Document.prototype 的对象:

      Document.prototype.isPrototypeOf(document) // true
      

      并且不拥有名为“cookie”的属性,Document.prototype 拥有:

      document.hasOwnProperty('cookie'); // false
      Document.prototype.hasOwnProperty('cookie'); // true
      

      获取document.cookie描述符的一种方法是获取Document.prototype.cookie本身的描述符:

      Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
      

      名为 __lookupGetter____lookupSetter__ 的已弃用函数实际上会遍历原型链,因此,您可以在 document 上检索这些调用它的方法,并且不是 Document.prototype

      const cookieDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
      cookieDescriptor.get === document.__lookupGetter__('cookie') // true
      

      【讨论】:

      • +1 因为有可行的用例(一个自建的 cookie jar 可以更轻松地访问和设置 cookie),特别是如果您想防止其他脚本通过公共 cookie API 进行干扰(您需要在检索到它们后从 Document.prototype 中删除 getter/setter)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 2016-02-24
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多