日期:2014-05-16 浏览次数:20390 次
前几天有人问我为什么点击链接后页面变成了一个只有“false”的页面,我猜想大概是滥用了javascript:伪协议吧。最终因为没让我看出事的代码,真正原因也就不得而知。不过我借此契机理清了此处疑惑,倒也算有所得了。
?
一般说来,伪协议经常被用到<a>的href属性上,例如<a href="javascript:alert('hello');">。这样,点击此链接的默认行为就是弹出一个框,而不是跳转至某页面了。此处需要注意的地方有两点:
1,返回值对浏览器行为的影响。返回undefined,停留在原页面,其它跳转至返回值。这就是为什么出现“false”页面的原因了。旧代码中能看到javascript:void(...);的写法,其实也是为了生成一个undefined的返回值,等同于在最后直接加return;。
2,this指向global变量。这不是说例子中alert里的this是global变量,而是连href属性里的this是global变量。因为此处是默认行为,不是事件,所以里面的代码的执行上下文不是触发元素。
?
伪协议还可以使用在form元素的action里,行为和使用在anchor上一样。至于其它地方可不可以使用,或者有没有什么其它细节之类的,我就觉得没有了解的必要了,毕竟这是一种已经不推荐使用的技术了,即混淆了结构又没有适当的fallback。
?
附上测试的代码,我觉得能运行的代码往往说明的能力更强。
<!DOCTYPE html> <html> <head> <title>My Test Page</title> </head> <body> <div> <form id="f" action="javascript:alertThis(this, 'action');" onsubmit="alertThis(this, 'submit');"> <div><input type="submit" value="Empty form" /></div> </form> <a href="javascript:alertThis(this, 'anchor');" onclick="alertThis(this, 'click');">empty anchor</a> </div> </body> <script type="text/javascript"> var logger = typeof(console) === 'object' ? console : {}; if (!logger.log) logger.log = alert; function alertThis() { logger.log("this is " + this + "\nargs[0] is " + arguments[0] + "\nargs[1] is " + arguments[1]); } </script> </html>?