检索 document.cookie getter 和 setter
Retrieving document.cookie getter and setter
我正在尝试覆盖 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);
Could someone explain me this behaviour?
document.cookie
是 host object. Host objects are frequently not true JavaScript objects (called native objects 的 属性),既不需要也不保证具有 JavaScript 对象的特征。
事实上,如果许多甚至超过一两个浏览器使用 ES5 属性 getters/setters 实现 document.cookie
,我会感到非常震惊。也许对于一些较新的 API(或者可能不是),但对于那些旧的 API,将会有很多麻烦。 (我还得考虑很长时间的安全后果...)
如果他们确实通过 ES5 getters/setters 实现了它,如果他们将其设为不可配置[=23],我也不会感到惊讶=] 属性(例如,您无法更改它)。
您可以使用 __lookupSetter__
和 __lookupGetter__
方法,但请注意,它们已被弃用并且并非在任何地方都受支持。它们在 Chrome、Firefox、IE11 中正常工作。不要在 IE <10 中工作。 Opera 提供了这样的方法,但它们总是 return 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
});
原因
Object.getOwnPropertyDescriptor(document, 'cookie');
返回 undefined 是 getOwnPropertyDescriptor 的工作方式:它不遍历原型链。
全局变量 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
我正在尝试覆盖 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);
Could someone explain me this behaviour?
document.cookie
是 host object. Host objects are frequently not true JavaScript objects (called native objects 的 属性),既不需要也不保证具有 JavaScript 对象的特征。
事实上,如果许多甚至超过一两个浏览器使用 ES5 属性 getters/setters 实现 document.cookie
,我会感到非常震惊。也许对于一些较新的 API(或者可能不是),但对于那些旧的 API,将会有很多麻烦。 (我还得考虑很长时间的安全后果...)
如果他们确实通过 ES5 getters/setters 实现了它,如果他们将其设为不可配置[=23],我也不会感到惊讶=] 属性(例如,您无法更改它)。
您可以使用 __lookupSetter__
和 __lookupGetter__
方法,但请注意,它们已被弃用并且并非在任何地方都受支持。它们在 Chrome、Firefox、IE11 中正常工作。不要在 IE <10 中工作。 Opera 提供了这样的方法,但它们总是 return 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
});
原因
Object.getOwnPropertyDescriptor(document, 'cookie');
返回 undefined 是 getOwnPropertyDescriptor 的工作方式:它不遍历原型链。
全局变量 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