同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 &quot;$(MSBuildProjectDirectory)\..\Libs\gogole-closure-compiler.jar&quot; --compilation_level ADVANCED_OPTIMIZATIONS --js $(_PackageTempDir)\myjs.js &gt;&gt; $(_PackageTempDir)\myjs-compressed.js" />
<Delete Files="&quot;$(_PackageTempDir)\myjs.js&quot;">
</Delete>
<Move SourceFiles="$(_PackageTempDir)\myjs-compressed.js" DestinationFiles="$(_PackageTempDir)\myjs.js">
</Move>
<Delete Files="&quot;$(_PackageTempDir)\myjs-compressed.js&quot;">
</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的更多相关文章

  1. 在Visual Studio 2012中使用VMSDK开发领域特定语言(一)

    前言 本专题主要介绍在Visual Studio 2012中使用Visualization & Modeling SDK进行领域特定语言(DSL)的开发,包括两个部分的内容.在第一部分中,将对 ...

  2. 在Visual Studio 2012中使用VMSDK开发领域特定语言1

    在Visual Studio 2012中使用VMSDK开发领域特定语言(一)   前言 本专题主要介绍在Visual Studio 2012中使用Visualization & Modelin ...

  3. 【转载】在 Visual Studio 2012 中创建 ASP.Net Web Service

    在 Visual Studio 2012 中创建 ASP.Net Web Service,步骤非常简单.如下: 第一步:创建一个“ASP.Net Empty Web Application”项目 创建 ...

  4. 在Visual Studio 2012中使用ASP.NET MVC5

    去年11月,.NET团队发布了用于 Visual Studio 2012 的 ASP.NET 和 Web 工具 2013.1 您可以从下面提供的链接下载该更新:  下载用于 Visual Studio ...

  5. 在Visual Studio 2012中使用VMSDK开发领域特定语言(二)

    本文为<在Visual Studio 2012中使用VMSDK开发领域特定语言>专题文章的第二部分,在这部分内容中,将以实际应用为例,介绍开发DSL的主要步骤,包括设计.定制.调试.发布以 ...

  6. 如何在"Visual Studio Code"中使用" Git" 进行版本控制

    如何在"Visual Studio Code"中使用" Git" 进行版本控制 本来认为此类教程,肯定是满网飞了.今天首次使用VS Code的Git功能,翻遍了 ...

  7. 如何在Visual Studio 2017中使用C# 7+语法 构建NetCore应用框架之实战篇(二):BitAdminCore框架定位及架构 构建NetCore应用框架之实战篇系列 构建NetCore应用框架之实战篇(一):什么是框架,如何设计一个框架 NetCore入门篇:(十二)在IIS中部署Net Core程序

    如何在Visual Studio 2017中使用C# 7+语法   前言 之前不知看过哪位前辈的博文有点印象C# 7控制台开始支持执行异步方法,然后闲来无事,搞着,搞着没搞出来,然后就写了这篇博文,不 ...

  8. [开发笔记]-Visual Studio 2012中为创建的类添加注释的模板

    为类文件添加注释,可以让我们在写代码时能够方便的查看这个类文件是为了实现哪些功能而写的. 一:修改类文件模板 找到类模版的位置:C:\Program Files (x86)\Microsoft Vis ...

  9. 用 Visual Studio 2012 调试你的ASP程序

    最近搞到一段很值得参考的ASP项目,无奈技术有限,打开看完代码后感觉自己就像从来没学过ASP一样.唉...大神的世界 不过在网上看到一个有趣的方法,可以用Visual Studio 2005来调试AS ...

随机推荐

  1. Codeforces Round #388 (Div. 2) - C

    题目链接:http://codeforces.com/contest/749/problem/C 题意:给定一个长度为n的D/R序列,代表每个人的派别,然后进行发表意见,顺序是从1到n.每个人到他的回 ...

  2. 如何创建独立的UE4服务端

    原文作者:@玄冬Wong 转载请注明原文出处:http://aigo.iteye.com/blog/2268777 这是论坛上对UE服务端功能的回答,意思是UE4提供了主流MMO网游服务端所具备的特性 ...

  3. 【转】iOS学习之translucent属性

    原文地址:http://www.jianshu.com/p/930643270455 总所周知,苹果从iOS7开始采用扁平化的界面风格,颠覆了果粉们"迷恋"的拟物化风格.对于开发者 ...

  4. MVC Html.BeginForm 与 Ajax.BeginForm 使用总结

    最近采用一边工作一边学习的方式使用MVC5+EF6做一个Demo项目, 期间遇到不少问题, 一直处于研究状态, 没能来得及记录. 今天项目进度告一段落, 得以有空记录学习中遇到的一些问题. 由于MVC ...

  5. 半吊子学习Swift--天气预报程序-获取天气信息

    昨天申请的彩云天气Api开发者今天上午已审核通过  饭后运动过后就马不停蹄的来测试接口,接口是采用经纬度的方式来获取天气信息,接口地址如下 https://api.caiyunapp.com/v2/ ...

  6. struts2 框架处理流程

    struts2 框架处理流程 流程图如下: 注意:StrutsPrepareAndExecuteFilter替代了2.1.3以前的FilterDispatcher过滤器,使得在执行Action之前可以 ...

  7. phantomjs 双向认证,访问nginx,https

    应用背景: phantomjs的一个爬虫,访问https站点,单向认证(只认证服务器身份)的都可以,双向认证(服务器和客户端都需要认证)必须上传本地证书: 开始用一个包含公钥私钥的PEM证书访问,怎么 ...

  8. UML类图关系--继承(泛化)、实现、关联、聚合、组合、依赖

    在UML类图中,常见的有以下几种关系:  泛化(Generalization),  实现(Realization),关联(Association),聚合(Aggregation),组合(Composi ...

  9. Map的keySet和entrySet

    /*Map集合的两种 取出方式 * 1.keySet() * 2.entrySet() * */ //定义一个学生类 重写了equals.hashcode三个方法,实现了comparable接口并覆盖 ...

  10. USACO翻译:USACO 2012 FEB Silver三题

    USACO 2012 FEB SILVER 一.题目概览 中文题目名称 矩形草地 奶牛IDs 搬家 英文题目名称 planting cowids relocate 可执行文件名 planting co ...