我试图覆盖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);

答案 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.cookie
是host object的属性。主机对象通常不是真正的JavaScript对象(称为native objects),既不需要也不保证具有JavaScript对象的功能。
事实上,如果使用ES5属性getter / setter实现document.cookie
许多甚至超过一个或两个浏览器,我会感到非常震惊。也许对于一些较新的API(或许不是),但对于那些旧的API,会有很多不足之处。 (我还需要考虑很长时间的安全后果......)
如果他们 通过ES5 getter / setter实现它,那么如果他们将其设为不可配置的属性(例如,你不能这样做)就不会让我感到惊讶不要改变它。