据我所知,ES规范说Proxy
(用于代理对象,函数和类的全局构造函数)是不可检测的。这意味着如果我代理一个函数,那么使用该代理函数的人都无法检测到我使用了代理。但是,显然我误解了它,因为可以检测到代理功能。
例如,new Proxy(a=>a,{apply:a=>a})+''
会抛出错误。它说
Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function
但是,typeof new Proxy(a=>a,{apply:a=>a})
确实是"function"
,但它在某种程度上无法对代理进行字符串化。因此,显然,这是一种情况,当代理函数不像非代理函数那样表现时。 Function.prototype.toString
能够区分代理和非代理功能。
我的目标是代理一个功能,使其变得简单无法检测。我的第一个想法是按字面意思代理代理,如下:
Proxy.toString = (a => () => a)(Proxy + '');
Proxy = new Proxy(Proxy, {
construct: (f, args) => {
if(typeof args[0] == 'function'){
var a = args[0] + '';
args[0].toString = () => a;
}
return new f(...args);
}
});
但遗憾的是,这是可以察觉的。如果有人将Function.prototype.toString
绑定到我的代理函数,则会发生错误,因此他可以检测到我的函数实际上是代理。所以,我尝试代理Function
和Function.prototype
以及Function.prototype.toString
,但后来我意识到我无法代理Function
,因为即使我覆盖了全局属性{{1有人可以使用Function
访问它。
所以,这就是我在这里问的原因,因为我没有想法。如何代理函数使其完全无法检测?在ES规范中明确指出“代理是不可检测的”,所以作为一个附带问题,为什么然后代理一个可检测的函数?
我试图实现此目的的原因是因为我正在为Chrome增强广告拦截扩展功能。我正在处理非常激进的网站,利用大量的JavaScript技巧来检测我是否正在查看广告。所以,基本上,我删除了一个广告,然后他们的脚本检查是否有特定元素,如果没有,那么我不能访问该网站。所以,我试图代理(a=>a).constructor
,但他们检查它是否被代理,如果是,我不能访问该网站,所以我必须让它无法检测。
答案 0 :(得分:0)
我不认为你可以用Proxies做什么。 Function.prototype.toString
的{{3}}清楚地定义了TypeError
投掷行为。由于无法提供Proxy
[[ECMAScriptCode]]
“内部广告位”,因此在Proxy
上调用时总是会抛出。
我也没有在规范中看到任何“代理是不可检测的”语句;字符串'detectable'不会显示在文档中的任何位置。你在哪里找到这个说法?
也许你可以覆盖函数(以及它们的.toString
属性)来实现你的目标?大致是:
var original_getElementById = document.getElementById;
document.getElementById = function(id) {
if (...) {
return original_getElementById(id);
} else {
// special handling here
}
}