我们都知道JavaScript是一种在客户端浏览器中执行的解释型语言。浏览器以纯文本的形式下载JavaScript,然后
在需要的时候执行JavaScript代码。
通过使用浏览器的查看源代码功能,用户总是能够阅读JavaScript的源代码,该功能会显示页面的完整HTML代码,
包括任何JavaScript代码块。即使JavaScript源代码被放在一个外部文件中并通过script标签的src属性引用到页面
中,它仍然可以被用户下载并阅读。对于任何查看页面的人
来说,JavaScript代码永远是可见的。正因为这一点,不应该在JavaScript中编写私有的或敏感的逻辑。这种逻辑
最好放在服务器端,那里更安全。
随着在基于Ajax的应用中越来越多地使用JavaScript,JavaScript源文件的大小也会成为一个问题。因为是解释型
语言,所以
JavaScript永远不会被编译成机器级的二进制码,而后者是一种更高效的可执行代码存储格式。大量的JavaScript
文件会降低应用的速度,因为在执行这些JavaScript之前,浏览器必须先从服务器下载这些源代码。此外,如果代
码中的注释很多的话,庞大的JavaScript代码只会变得更庞大
。
我们可以看出,JavaScript缺少二进制可执行代码的特性有两个问题:糟糕的安全性以及需要下载大量源代码。有
什么办法可以解决这两个问题吗?
随着
JavaScript变得越来越流行,已经有了一些工具可以帮助我们解决这两个问题。最简单的压缩工具只是去掉JavaSc
ript源代码中的所有注释和换行符,这就可以减少需要下载的源代码量。删除注释和换行符可以减少30%或更多的
JavaScript源代码量,这要视情况而定。需要注意的是,在被
这种工具压缩之前,JavaScript源代码必须使用分号正确地结束所有的声明,不然就会产生错误或非预期的行为。
记住,虽然JavaScript语句总是应该以分号结束,但大多数浏览器还是很宽容的,它们允许不写这种分号,只要在
本应是分号的地方有一个换行符。很多压缩器都会除去换行符,当声明没有使用分号结束时,这就会对JavaScript
源文件产生非预期的结果。JavaScript并没有一个编译器来捕
捉这种问题,因此,应该代之以使用JavaScript验证器来保证所有行都以分号结束,所有声明块都使用了大括号。
一个很不错的JavaScript验证器是
JSLint,可以从www.jslint.com下载它。总是在压缩JavaScript之前使用像JSLint这样的JavaScript验证器会帮助
我们防止压缩及混淆非常规JavaScript所造成的错误。
另外一些工具更强大一些,它们提供混淆功能。混淆是一种扫描源代码的过程,这个过程会把字段和函数本来的名
字修改为经过编码的、毫无意义的名字,以此来防止他人了解源代码的目的和内部结构。通常,像C++这样的语言是
不需要混淆的,因为它会被编译成机器级的二进制指令。为
了达到很高的安全性,即便是像Java或 C#这样被编译成中间字节码而不是二进制指令的现代语言也需要使用混淆工
具。
由于 JavaScript解释型的本质,编写JavaScript混淆工具是极具挑战性的。在确定函数名的作用域和可见性、函数
变量以及全局变量方面,
JavaScript混淆工具可能是有困难的,结果是,压缩后的源代码往往不能正确运行。单凭经验来讲,最佳方法就是
避免把敏感的或私密的逻辑暴露在 JavaScript中,尽量把它们放在服务器端,它们在那里是安全的。如果你坚持要
使用JavaScript混淆器,那么一定要彻底地测试混淆后的
JavaScript,确保它仍然能够正常工作。
Dojo工具包的JavaScript压缩器
目前,广大开发人员普遍使用的JavaScript压缩器和混淆器是由Dojo工具包提供的,其下载网址是
www.dojotoolkit.org/docs/compressor_system.html。与很多JavaScript压缩器一样,Dojo的压缩器也是通过除去
注释和运算符两边的空格、用更短的名字替换变量名这样的手段来压缩JavaScript源文件的。稍等——替换函数名
和变量名听起来很费解。我们不是刚刚说过由于混淆所带来
的问题,应该尽量避免使用它吗?
Dojo
压缩器与其同类工具的不同之处在于其压缩并混淆JavaScript源代码的方式。很多JavaScript混淆器使用正则表达
式来除去空格和注释。正则表达式很容易失效,而且也不具备上下文信息,而上下文正是决定变量名作用域的关键
。Dojo压缩器使用Mozilla基金会提供的JavaScript引擎Rhino
。
Rhino使得Dojo压缩器具有了确定变量名上下文和作用域的能力。因为Rhino是一款实时JavaScript解释器,所以Do
jo压缩器能够确定变量名的作用域并安全地缩短变量名,而不会造成任何问题。
Dojo
压缩器的主要目的是维护公共API的兼容性,并确保压缩后的脚本功能与压缩前完全一致。即使Dojo压缩器缩短了变
量名,那也是为了缩小文件,而不是为了混淆。Dojo压缩器的创建者们认为混淆JavaScript是没有意义的,但是缩
小文件无疑非常有意义。为此,Dojo压缩器试图在缩小文件
与可读性和可调试性之间达成良好的平衡。
在需要的时候执行JavaScript代码。
通过使用浏览器的查看源代码功能,用户总是能够阅读JavaScript的源代码,该功能会显示页面的完整HTML代码,
包括任何JavaScript代码块。即使JavaScript源代码被放在一个外部文件中并通过script标签的src属性引用到页面
中,它仍然可以被用户下载并阅读。对于任何查看页面的人
来说,JavaScript代码永远是可见的。正因为这一点,不应该在JavaScript中编写私有的或敏感的逻辑。这种逻辑
最好放在服务器端,那里更安全。
随着在基于Ajax的应用中越来越多地使用JavaScript,JavaScript源文件的大小也会成为一个问题。因为是解释型
语言,所以
JavaScript永远不会被编译成机器级的二进制码,而后者是一种更高效的可执行代码存储格式。大量的JavaScript
文件会降低应用的速度,因为在执行这些JavaScript之前,浏览器必须先从服务器下载这些源代码。此外,如果代
码中的注释很多的话,庞大的JavaScript代码只会变得更庞大
。
我们可以看出,JavaScript缺少二进制可执行代码的特性有两个问题:糟糕的安全性以及需要下载大量源代码。有
什么办法可以解决这两个问题吗?
随着
JavaScript变得越来越流行,已经有了一些工具可以帮助我们解决这两个问题。最简单的压缩工具只是去掉JavaSc
ript源代码中的所有注释和换行符,这就可以减少需要下载的源代码量。删除注释和换行符可以减少30%或更多的
JavaScript源代码量,这要视情况而定。需要注意的是,在被
这种工具压缩之前,JavaScript源代码必须使用分号正确地结束所有的声明,不然就会产生错误或非预期的行为。
记住,虽然JavaScript语句总是应该以分号结束,但大多数浏览器还是很宽容的,它们允许不写这种分号,只要在
本应是分号的地方有一个换行符。很多压缩器都会除去换行符,当声明没有使用分号结束时,这就会对JavaScript
源文件产生非预期的结果。JavaScript并没有一个编译器来捕
捉这种问题,因此,应该代之以使用JavaScript验证器来保证所有行都以分号结束,所有声明块都使用了大括号。
一个很不错的JavaScript验证器是
JSLint,可以从www.jslint.com下载它。总是在压缩JavaScript之前使用像JSLint这样的JavaScript验证器会帮助
我们防止压缩及混淆非常规JavaScript所造成的错误。
另外一些工具更强大一些,它们提供混淆功能。混淆是一种扫描源代码的过程,这个过程会把字段和函数本来的名
字修改为经过编码的、毫无意义的名字,以此来防止他人了解源代码的目的和内部结构。通常,像C++这样的语言是
不需要混淆的,因为它会被编译成机器级的二进制指令。为
了达到很高的安全性,即便是像Java或 C#这样被编译成中间字节码而不是二进制指令的现代语言也需要使用混淆工
具。
由于 JavaScript解释型的本质,编写JavaScript混淆工具是极具挑战性的。在确定函数名的作用域和可见性、函数
变量以及全局变量方面,
JavaScript混淆工具可能是有困难的,结果是,压缩后的源代码往往不能正确运行。单凭经验来讲,最佳方法就是
避免把敏感的或私密的逻辑暴露在 JavaScript中,尽量把它们放在服务器端,它们在那里是安全的。如果你坚持要
使用JavaScript混淆器,那么一定要彻底地测试混淆后的
JavaScript,确保它仍然能够正常工作。
Dojo工具包的JavaScript压缩器
目前,广大开发人员普遍使用的JavaScript压缩器和混淆器是由Dojo工具包提供的,其下载网址是
www.dojotoolkit.org/docs/compressor_system.html。与很多JavaScript压缩器一样,Dojo的压缩器也是通过除去
注释和运算符两边的空格、用更短的名字替换变量名这样的手段来压缩JavaScript源文件的。稍等——替换函数名
和变量名听起来很费解。我们不是刚刚说过由于混淆所带来
的问题,应该尽量避免使用它吗?
Dojo
压缩器与其同类工具的不同之处在于其压缩并混淆JavaScript源代码的方式。很多JavaScript混淆器使用正则表达
式来除去空格和注释。正则表达式很容易失效,而且也不具备上下文信息,而上下文正是决定变量名作用域的关键
。Dojo压缩器使用Mozilla基金会提供的JavaScript引擎Rhino
。
Rhino使得Dojo压缩器具有了确定变量名上下文和作用域的能力。因为Rhino是一款实时JavaScript解释器,所以Do
jo压缩器能够确定变量名的作用域并安全地缩短变量名,而不会造成任何问题。
Dojo
压缩器的主要目的是维护公共API的兼容性,并确保压缩后的脚本功能与压缩前完全一致。即使Dojo压缩器缩短了变
量名,那也是为了缩小文件,而不是为了混淆。Dojo压缩器的创建者们认为混淆JavaScript是没有意义的,但是缩
小文件无疑非常有意义。为此,Dojo压缩器试图在缩小文件
与可读性和可调试性之间达成良好的平衡。