小心HTML comment
咱好歹也是一professional web developer了。这里面陷阱真多啊。比如HTML comment:
http://webtips.dan.info/comments.html
我查这个问题主要是因为我的JS comment写成了/*-----------XXX---------*/而通不过validation。遂使用下列RE替换:
/\*-+([^-]*)-+\*/
/\*=======$1=======\*/
咱好歹也是一professional web developer了。这里面陷阱真多啊。比如HTML comment:
http://webtips.dan.info/comments.html
我查这个问题主要是因为我的JS comment写成了/*-----------XXX---------*/而通不过validation。遂使用下列RE替换:
/\*-+([^-]*)-+\*/
/\*=======$1=======\*/
http://blog.csdn.net/g9yuayon/archive/2007/04/18/1568980.aspx
这篇贴挺有意思的。几位老兄讨论了半天,全错了。
这段代码根本没定义出闭包。匿名函数里访问e,但由于JavaScript没有block-level scope,e其实是全局变量,而不是局部变量。所以在这段代码执行完,e总是"onmouseover"。当事件被触发的时候,解释器尝试解析e,只找到全局的这个,所以events[e]总是"mouse over"。
嘿嘿,真有意思。
Oh let's face it: it's fun!
The "onclick" attribute of the element (or any other element) is part of the JavaScript event model, but the "href" is NOT. Effectively, when you're writing "javascript: something" in an href, you're writing a URI. So "this" would refer to the window here. On the other hand, if you're writing in an onclick, the code you wrote will be wrapped into a handler function, in which "this" refers to the element itself.
Oh I should add that, you can also write "javascirpt:" in onXXX. in this case, "javascript:" is a legal LABEL in the JavaScript language since it appears in JS code.
About the event listener, come back to these code if anything troubles you:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Insert title here</title>
</head>
<body>
<div id="mydiv" onclick="alert('div bubble0')"><a id="mylink"
onclick="alert('link')">link</a></div>
<script type="application/javascript">
document.getElementById('mydiv').addEventListener('click', function(e){alert('div prop1')}, true)
document.getElementById('mydiv').addEventListener('click', function(e){alert('div prop2')}, true)
document.getElementById('mydiv').addEventListener('click', function(e){alert('div bubble1')}, false)
document.getElementById('mydiv').addEventListener('click', function(e){alert('div bubble2')}, false)
</script>
</body>
</html>
这些日子独立完成了系统里的一个被我们称为“select all”的复杂功能,自己很得意。本质上来说,整个过程是用一个有限状态机表示的,而这机器的状态,要使用服务器端的Java代码和客户端的JavaScript代码共同维护。我是先做出了完整的设计,然后写代码的时候一气呵成。尽管全部是自己做的,完成的时候还是惊叹这东西运行起来竟然极其精确,跟我设计的丝毫不差,完美的解决了问题。有些人说你这不是废话吗,都是你做的你还不知道。可是做软件的时候我总有这种感觉,就是,虽然知道代码会如何运行,完成的时候还是惊叹它们居然难以置信的、正确而且精准的,解决了问题,就好像问题不是自己解决的,而是计算机里的某个精灵在帮助自己一样。就像SICP的作者所说的,we conjure the spirits of the computer with our spells。
然后这两天又用零散的时间,用JavaScript实现了一个初看很困难的客户端组件。
我曾经仔细研究过JavaScript,但现在想想,当时对作用域,闭包等等没有现在理解的深入。所以这两天又再看犀牛书,这次就有针对性得多了。和当年一样,我特别讨厌网上好多人用术语唬人。我觉得你要是心里明白,不用术语就能说明白。或者你先把术语解释清楚。有好多次我都是搞明白一个术语的意思后,气不打一处来,咳,这不就是那啥那啥么,瞎忽悠什么啊,真不厚道。我决定以后每搞明白一个术语,就彻底解释一动,包括补上以前已经弄懂的一些东西。积累知识是我写博客最主要的一个目的,而且我不喜欢写技术中那些细枝末节的东西,因为这方面google远胜于我。我想表达的,是ideas & thoughts。
重点不是这点经验。重点是这些经验后隐藏着的思想。很多东西远远比它们所表现出来的更generic。
1. 复用不是那么容易的。如果不了解现有系统,时间也不允许你先了解现有系统(中国项目的特点),又需要复用一个模块。那么先复制一下做个新的模块,在上面改,比在原来模块基础上增加功能(以及随之而来的一堆判断)要容易得多。这不仅适用于Web开发。
2. Web程序每个URL的功能最好独立一点。比如用Struts的话,每个Action干的功能最好别超过两个。多了以后判断起来特麻烦,而且很多时候,根据参数的缺失情况也不是那么好判断。参见前一篇《Web程序输入分析》。这条要灵活使用。其实Linux里面很多命令或者软件功能非常单一,思想是一样的。简单的东西容易看懂,好维护,并且每个东西只干一件事更容易把事做好。
3. Struts Action中约定俗成不要写fields主要是为线程安全考虑。其实不是绝对不可以。可以配置成每次都生成新的Action实例,只是会降低效率。
4. JSP调试的可能需要app server的支持。比如Weblogic里要把JSP行号打开。(必须以exploded形式部署web module,然后进入descriptor页面即可。实际上就是修改了weblogic.xml。)
5. 方法/函数一定要短啊啊啊啊啊啊啊啊啊啊啊啊啊啊。理由见第二条。
6. 不要根据某些公用的、不是用作flag的对象状态来判断状态。这些东西没有被显式说明会被用到作为flag,因此别的代码可能会未经考虑就修改它们的状态。根据对象内部的private data member,做一个判断并输出状态的接口是没问题的。因为这些东西不会被外界不经意的改变。如果它们改变了,就意味着状态真的变了。
Web程序是琐碎而有趣的。其本质没有什么特殊,也是接受输入(最常见的是http request)产生输出(最常见的是http response)。区别在于,来自于网络的这些输入是来自所谓终端用户,而不是其他的程序员。这些用户可以非常不讲道理,甚至带着破坏系统的敌意,来提供输入(见我前面的一篇《XSS攻击的一种形式》)。所以我们实现web程序时,必须很细心的分析可能发生的各种情况。
输入错误的情况其实有两种。要分情况进行不同的处理。
一种是用户没有按照规定操作界面,比如用户在购物网站未经登录就点击我的购物车。这种情况下要回馈给用户相应的出错信息,引导客户进行正确的操作。
另一种是用户在正常使用界面时,不可能出现的情况。比如某些参数缺失等等。这些情况可能是黑客行为(构造的http request),或者是用户访问了不当的url造成的。这种情况说明对方在做我们不希望他们做的事,因此我们不应回馈任何错误信息。
并不是每次我们都能清楚的区分这两种情况,也并不是任何时候都有必要做最严密的防范。但至少要有这个意识。
参考:http://en.wikipedia.org/wiki/Xss
想写这个主要是因为,国外的一个客户找了一个网络安全公司对其J2EE系统进行了安全分析,并在其中找到了一些问题。说实话我真的很佩服这种问题都能被挖出来,因为它们是一些很hacking的问题,同时非常有趣。