我刚刚发现我们可以拦截javascript alert()本机调用并在实际执行之前挂钩用户代码。看看示例代码..
function Test(){
var alertHook=function(aa){
this.alert(aa);
}
this.alert("aa");
this.alert = alertHook;
alert("aa");
}
所以我每次调用alert(“aa”)都被我的alertHook本地函数截获。但是以下实施的小改动不起作用。
function Test(){
var alertHook=function(aa){
alert(aa);
}
alert("aa");
alert = alertHook; //throws Microsoft JScript runtime error: Object doesn't support this action
alert("aa");
}
它抛出 Microsoft JScript运行时错误:对象不支持此操作。
我不知道这个 .alert = alertHook;让我拦截电话,但是警报= alertHook;不。??
所以我假设使用它来拦截任何原生的js方法。是对的吗?
这是可以接受的吗?因为这样我可以用我自己的方法完全替换任何本机JS调用吗?
更新
我问的是可以接受的吗?因为这是一个很好的方法,有eval()并让用户替换本机函数调用?它的语言保护开发人员免受误导性功能的影响,在窗口级别(或在通用框架js文件中)替换本机js调用会使整个系统崩溃..不是吗??
我认为我可能是错的,因为我不明白这个功能背后的原因..?我从未见过让开发人员替换自己的实现的语言。
答案 0 :(得分:3)
根据Test();
的调用方式,this
应为window
对象。
我相信Microsoft只允许通过指定窗口对象来覆盖本机JS函数。
所以window.alert = alertHook;
应该适用于任何地方。
可以接受吗?
是的。这是语言灵活性的一个主要优势,虽然我确信有更好的选择,而不是覆盖原生行为。
覆盖原生JavaScript函数并不是一个真正的安全问题。如果你正在运行别人的代码,它可能就是一个;但如果您正在运行别人的代码,那么您应该关注许多其他安全问题。
答案 1 :(得分:0)
在我看来,重新定义原生函数绝不是一种好习惯。使用包装器会更好(例如,创建一个debug
函数,将其输出定向到alert
或console.log
或忽略调用或任何适合您需要的函数。
至于为什么JScript会在你的第二个例子而不是第一个例子中引发异常,这很简单。在第一个示例中,您在本地范围内创建了一个名为alert
的属性,因此当您引用alert
时,您将引用this.alert
而不是window.alert
。在第二个示例中,您引用的alert
是来自window
的{{1}},因此为其分配不同的函数将失败。
答案 2 :(得分:0)
它的语言保护开发人员免受误导性功能的影响,在窗口级别(或在通用框架js文件中)替换本机js调用会使整个系统崩溃..不是吗??
不正确,将原生调用替换为仅挂钩,替换它:它根本不会重写本机。打破“整体”体系; JavaScript在虚拟机中运行,它被解释,因此崩溃“整个”系统(即蓝屏死机?)的可能性非常小。如果是这样:它不是程序员的错,而是导致错误的JavaScript的实现。
您可以将其视为一项功能:例如,如果您从其他人手中加载JavaScript,则可以重新实现某些功能以进行扩展。
保护程序员就像把狗放在皮带上:当你信任狗时,只释放它!由于JavaScript在虚拟机中运行,所以任何程序员都可以释放 - 如果实现足够安全,那么(大部分时间都是这样?)