同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. windows server 2008禁止ping

    在cmd命令行中通过ping一个主机名.域名或ip地址可以获取到该机器的ip.操作系统等很多信息,处于安全考虑,很多时候不希望服务器被ping,在windows server 2008 r2可以这样操 ...

  2. F#之旅0 - 开端

    F#之旅0 - 开端 UWP的学习告一段落,CozyRSS的UWP版本并没有做.UWP跟wpf开发几乎一模一样,然后又引入了很多针对移动设备的东西,这部分有点像android.没啥太大的意思,不难,估 ...

  3. Design and Implementation of the Sun Network File System

    Introduction The network file system(NFS) is a client/service application that provides shared file ...

  4. 安卓智能POS开单神器-成为零售批发商亲睐的生意帮手-pda销售扫描开单 现场结算打印凭据

    pda销售开单主要有盘点.出库.入库.销售等操作. 主要功能: 出库作业(销售开单.销售退货.销售赠品).入库作业(进货开单.进货退货.进货赠品).盘点作业(能盘盈盘亏)等操作,带蓝牙打印功能 3.仓 ...

  5. 第一天ci框架开发商城1

    ci框架开发商城1 1/28/2016 9:43:52 PM userguide删除 system application controllers 控制器 models 模型 views 视图 模板 ...

  6. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  7. Mac下搭建hexo

    Mac下搭建hexo 并部署到gitcafe 1.安装brewhome ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homeb ...

  8. IOS UIAlertController 使用方法

    在很多种语言中,alert都表示弹窗操作,弹窗功能非常有用,不仅可以用于正式的app功能中,也可以在调试中使用.在OC中,UIAlertController类用来控制弹窗操作.在IOS 8.0之前, ...

  9. 选择列表中除了第一个li的其他元素

    //选择div中除了第一个li的其他所以li元素 div li:not(:first-child){ }

  10. Mysql 学习笔记2

    (1)MySQL查看表占用空间大小 //先进去MySQL自带管理库:information_schema //自己的数据库:dbwww58com_kuchecarlib //自己的表:t_carmod ...