document.cookie 的代理
Proxying of document.cookie
我需要记录 document.cookie 的设置。我无法仅使用 document.cookie = {...}
重新定义 cookie 属性,因此我需要为 document.cookie 获取 setter。但是 Object.getOwnPropertyDescriptor(document, "cookie")
returns undefined
.
更新。当我写这个问题时,我找到了一个可行的解决方案,但它使用了已弃用的 __lookupGetter__
和 __lookupSetter__
方法。有没有不使用过时的API的解决方案?
在我写问题的时候,我发现下一个代码解决了我的问题:
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);
}
});
但我不喜欢使用过时的方法,所以我希望有更好的解决方案。
访问 getters 和 setters 的标准化方式是使用 Object.getOwnPropertyDescriptor
,但顾名思义,它只查看对象自身的属性(不查看原型链)。 document
是 HTMLDocument
的实例,它继承自 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__
或 __lookupSetter__
也不是。所以我还没有找到在 Safari 中覆盖 document.cookie
的方法(OS X 上的 8.0.8 和 iOS 9.0.2)。 WebKit nightly 的行为方式与 Safari 相同,因此它似乎不会很快得到修复。
2019 年 10 月更新: 在 MacOS Mojave 上的 Safari 12.1.2 中测试了上述代码,cookieDesk
现在可以配置了!这意味着我 2015 年的 proof of concept document.cookie
protection 现在可能真的有用了:)
我需要记录 document.cookie 的设置。我无法仅使用 document.cookie = {...}
重新定义 cookie 属性,因此我需要为 document.cookie 获取 setter。但是 Object.getOwnPropertyDescriptor(document, "cookie")
returns undefined
.
更新。当我写这个问题时,我找到了一个可行的解决方案,但它使用了已弃用的 __lookupGetter__
和 __lookupSetter__
方法。有没有不使用过时的API的解决方案?
在我写问题的时候,我发现下一个代码解决了我的问题:
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);
}
});
但我不喜欢使用过时的方法,所以我希望有更好的解决方案。
访问 getters 和 setters 的标准化方式是使用 Object.getOwnPropertyDescriptor
,但顾名思义,它只查看对象自身的属性(不查看原型链)。 document
是 HTMLDocument
的实例,它继承自 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__
或 __lookupSetter__
也不是。所以我还没有找到在 Safari 中覆盖 document.cookie
的方法(OS X 上的 8.0.8 和 iOS 9.0.2)。 WebKit nightly 的行为方式与 Safari 相同,因此它似乎不会很快得到修复。
2019 年 10 月更新: 在 MacOS Mojave 上的 Safari 12.1.2 中测试了上述代码,cookieDesk
现在可以配置了!这意味着我 2015 年的 proof of concept document.cookie
protection 现在可能真的有用了:)