同Java、.NET实现的应用程序类似,Javascript编写的应用程序也面临一个同样的问题:源代码的保护。尽管对大多数Javascript应用公开源代码不算是很严重的问题,但是对于某些开发者来说,特别是HTML5、WebGL和其它纯Javascript实现的项目,知识产权保护是不能忽视的,保护好源代码至少可以增加竞争对手山寨你的应用的成本。通过混淆Javascript代码的方法,可以降低代码的可读性,在一定程度上保护源代码;同时,混淆算法多数都会用非常短的变量名,因此混淆后的代码往往体积更小,网络传输效率和加载运行的效率更高一些。
Javascript代码混淆工具
目前各种开源的或商业的Javascript混淆工具比较多,笔者推荐的是google的。简单的混淆工具通常只做到语法分析的层面,只能重命名函数的参数和函数中var定义的变量。closure compiler是一个用Java编写的Javascript解释执行器,实现上能够完全运行Javascript代码,因此实现了更高级别的混淆,对对象的属性和对象原型中的属性都能够识别和混淆,生成完全混淆的代码。
closure compiler可以下载到本地通过命令行的方式运行,或者通过google提供的WebUI或WebService运行。
本文要在VS发布时应用,因此使用本地命令行的方式运行。
下载closure compiler到本地,进入解压缩后的文件夹,应该包含一个compiler.jar的文件。在该目录下新建一个myjs.js文件,拷一些js代码到该文件。确保本机已安装最新的Java。然后打开控制台,在该目录下运行如下命令:
java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js myjs.js >> myjs-compressed.js
在myjs-compressed.js中就可以看到混淆的结果。
这是手工运行compiler.jar的方法。这一步试验成功后,就可以在vs中在发布时运行该命令来混淆发布的代码。
在Visual Studio 2012中发布时运行混淆工具
Visual Studio的发布过程都是高度可配置的,可以在发布的过程中执行自定义的操作。发布过程的配置使用与MSBuild一致的配置语法。
在Web项目上点击发布,到本地文件夹或ftp等都可以,VS会创建一个名为"配置名称.pubxml"的发布配置文件,位于Properties\PublishProfiles文件夹下。打开该文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<!--
您 Web 项目的发布/打包进程将使用此文件。您可以通过编辑此 MSBuild 文件
来自定义该进程的行为。若要了解与此相关的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=208121。
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\Users\whf\Documents\Visual Studio \Projects\WebApplication2\trunk\WebApplication2\publish</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
这是选择发布到本地文件夹的一个配置,发布方式对本文无影响。
我们可以在项目已经发布到临时文件夹但是还没有发布到目标文件夹时增加一个Target(Target是MSBuild配置中的一个概念,包含一系列要执行的操作,详见MSDN),在发布临时文件夹下完成Javascript文件的混淆工作。
增加一个名为jsprocess的Javascript混淆Target后的发布配置文件如下:
<?xml version="1.0" encoding="utf-8"?>
<!--
您 Web 项目的发布/打包进程将使用此文件。您可以通过编辑此 MSBuild 文件
来自定义该进程的行为。若要了解与此相关的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=208121。
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:\Users\whf\Documents\Visual Studio \Projects\WebApplication2\trunk\WebApplication2\publish</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
<Target Name="jsprocess" AfterTargets="CopyAllFilesToSingleFolderForPackage">
<Exec Command="java -jar "$(MSBuildProjectDirectory)\..\Libs\gogole-closure-compiler.jar" --compilation_level ADVANCED_OPTIMIZATIONS --js $(_PackageTempDir)\myjs.js >> $(_PackageTempDir)\myjs-compressed.js" />
<Delete Files=""$(_PackageTempDir)\myjs.js"">
</Delete>
<Move SourceFiles="$(_PackageTempDir)\myjs-compressed.js" DestinationFiles="$(_PackageTempDir)\myjs.js">
</Move>
<Delete Files=""$(_PackageTempDir)\myjs-compressed.js"">
</Delete>
</Target>
</Project>
这个Target在内置的CopyAllFilesToSingleFolderForPackage Target之后运行,就是所有待发布文件都拷贝到了一个临时文件夹中,等待打包时,对于本地文件夹或ftp的发布方式,打包就是拷贝到目标文件夹。
我们定义的jsprocess执行了3个操作:
1)运行混淆工具 Exec(执行一个程序)
2)删除原始Javascript文件 Delete(删除文件)
3)重命名混淆后的Javascript文件为原始Javascript文件名 Move(移动文件) Delete
在这个示例中我将compiler.jar重命名为google-closure-compiler.jar并添加到了解决方案文件夹中,纳入源代码管理,其它同事获取最新版本后不需要任何配置就可以应用该功能。
通过适当修改上述代码,可以实现混淆所有.js文件。
closure对Javascript代码的要求
基本上,将你需要混淆的代码放在一个闭包中,以字符串索引的形式命名需要暴露的对象的名称和对象的属性的名称(因为closure不会改变Javascript源代码中任何字符串值),就可以用closure实现完美的混淆。
一个简单的示例,在Web项目中myjs.js的源代码如下:
//myjs.js
(function (window) { function PrivateClass() {
/// <summary>
/// 私有类
/// </summary>
/// <field name='someProperty1' type='String'>属性1</field>
/// <field name='someProperty2' type='Number'>属性2</field> this.someProperty1 = "";
this.someProperty2 = 0;
} PrivateClass.prototype.method1 = function () {
/// <summary>
/// 私有类原型的方法1。
/// </summary> // do some thing
} /// <var name='publicObject' type='Object'>对外暴露的公有对象</var>
var publicObject = {}; publicObject["publicMethod1"] = function () {
/// <summary>
/// 公有方法1。
/// </summary> var p = new PrivateClass();
p.someProperty1 = "sdfsdf";
p.someProperty2 = 23;
p.method1();
//do some thing
return "一些结果";
} window["publicObjectName"] = publicObject; })(window);
发布后的myjs.js内容如下:
(function(b){function c(){this.a="";this.b=0}b.publicObjectName={publicMethod1:function(){var a=new c;a.a="sdfsdf";a.b=23;return"\u4e00\u4e9b\u7ed3\u679c"}}})(window);
在html文件中就可以通过publicObjectName.publicMethod1访问myjs.js暴露的方法。其它诸如PrivateClass、someProperty1、method1等名称都将被混淆为a、b、c之类没有明确意义的名称。
可以注意到,除了重命名之外,closure还对代码进行了很多重构。
结论
通过在发布时实现Javascript的自动混淆,我们可以避免人工介入发布过程,提高发布效率。不管是因为项目性质缘故还是测试要求,项目的发布必然是非常频繁的,完全自动化的发布过程可以节约大量时间。同时,Javascript代码需要针对混淆做出些许修改,测试混淆后的代码而不是混淆前的也是必须的。
如何在Visual Studio 2012中发布Web应用程序时自动混淆Javascript的更多相关文章
-
在Visual Studio 2012中使用VMSDK开发领域特定语言(一)
前言 本专题主要介绍在Visual Studio 2012中使用Visualization & Modeling SDK进行领域特定语言(DSL)的开发,包括两个部分的内容.在第一部分中,将对 ...
-
在Visual Studio 2012中使用VMSDK开发领域特定语言1
在Visual Studio 2012中使用VMSDK开发领域特定语言(一) 前言 本专题主要介绍在Visual Studio 2012中使用Visualization & Modelin ...
-
【转载】在 Visual Studio 2012 中创建 ASP.Net Web Service
在 Visual Studio 2012 中创建 ASP.Net Web Service,步骤非常简单.如下: 第一步:创建一个“ASP.Net Empty Web Application”项目 创建 ...
-
在Visual Studio 2012中使用ASP.NET MVC5
去年11月,.NET团队发布了用于 Visual Studio 2012 的 ASP.NET 和 Web 工具 2013.1 您可以从下面提供的链接下载该更新: 下载用于 Visual Studio ...
-
在Visual Studio 2012中使用VMSDK开发领域特定语言(二)
本文为<在Visual Studio 2012中使用VMSDK开发领域特定语言>专题文章的第二部分,在这部分内容中,将以实际应用为例,介绍开发DSL的主要步骤,包括设计.定制.调试.发布以 ...
-
如何在";Visual Studio Code";中使用"; Git"; 进行版本控制
如何在"Visual Studio Code"中使用" Git" 进行版本控制 本来认为此类教程,肯定是满网飞了.今天首次使用VS Code的Git功能,翻遍了 ...
-
如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序
如何在Visual Studio 2017中使用C# 7+语法 前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...
-
[开发笔记]-Visual Studio 2012中为创建的类添加注释的模板
为类文件添加注释,可以让我们在写代码时能够方便的查看这个类文件是为了实现哪些功能而写的. 一:修改类文件模板 找到类模版的位置:C:\Program Files (x86)\Microsoft Vis ...
-
用 Visual Studio 2012 调试你的ASP程序
最近搞到一段很值得参考的ASP项目,无奈技术有限,打开看完代码后感觉自己就像从来没学过ASP一样.唉...大神的世界 不过在网上看到一个有趣的方法,可以用Visual Studio 2005来调试AS ...
随机推荐
-
Node使用multiparty包上传文件
var multiparty = require('multiparty'); var http = require('http'); var util = require('util'); var ...
-
VS-项目发布失败的解决方案1
报错信息 错误 1 未能将文件 Script\easyui\themes\gray\images\Thumbs.db 复制到 obj\Release\Package\PackageTmp\Script ...
-
python http代理代码
googlecode :https://code.google.com/archive/p/python-proxy/source/default/source # -*- coding: cp125 ...
-
POJ 1273 网络流(最大流)模板
http://poj.org/problem?id=1273 这道题很值得反思,弄了一下午,交上去先是一直编译错误,而在本地运行没有问题, 原因可能是oj的编译器版本老旧不支持这样的写法 G[from ...
-
equals 与 == 的区别和用法(C# &; Java)【转】
转至http://www.cnblogs.com/beeone/archive/2011/04/25/2026674.html public class TestString { public sta ...
-
(二)再议MII、RMII、GMII接口
概述: MII (Media Independent Interface(介质无关接口)或称为媒体独立接口,它是IEEE-802.3定义的以太网行业标准.它包括一个数据接口和一个MAC ...
-
利用wireshark任意获取qq好友IP实施精准定位
没事玩一把,感觉还挺有趣,首先打开wireshark: 不管你连接的什么网,如图我连接的是WLAN,双击进入如图界面: ctrl-f进行搜索:如图 选择分组详情,字符串,并输入020048.这时候你就 ...
-
Mac下Git安装及配置
Mac下: 1.下载git版本并安装 运行终端 查看git版本: bogon:~ yan$ git --version git version 2.16.3 配置gitconfig文件 vim ~/. ...
-
Go接口interface
目录 接口是什么? interface类型 空接口(interface{}) interface函数参数 interface变量存储的类型 类型断言 嵌入interface 接口是什么? Go 语言不 ...
-
js要怎么接收后端传的excel文件流?
方法1: 无需js,直接用a标签去接你的输出流 <a href="<你的返回流的Action路径>" >下载</a> 方法2:使用js,前提是你 ...