检索document.cookie getter和setter

时间:2015-06-06 16:42:07

标签: javascript cookies browser

我试图覆盖document.cookie,因为我需要控制cookie 创建,但似乎getOwnPropertyDescriptor在document.cookie上生成并没有检索它的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);




3 个答案:

答案 0 :(得分:4)

您可以使用__lookupSetter____lookupGetter__方法,但请注意它们已弃用且不受支持。它们可以在Chrome,Firefox,IE11中正常运行。不要在IE< 10中工作。 Opera提供了这样的方法,但是它们总是返回undefined。没有检查其他任何东西。

以下是一个例子:

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

答案 1 :(得分:3)

原因

Object.getOwnPropertyDescriptor(document, 'cookie');

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

全局变量文档包含实际继承自 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.prototype

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

答案 2 :(得分:1)

  

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

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

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

如果他们 通过ES5 getter / setter实现它,那么如果他们将其设为不可配置的属性(例如,你不能这样做)就不会让我感到惊讶不要改变它。