同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. linux 负载均衡

    [博文推荐]关于负载均衡技术使用的一些误区 如今,负载均衡已经不是一个新鲜的词,也不是什么新技术,主要用于解决单机负载能力的局限性,但问题是你的应用真的到了单 机的负载上限了吗,未必,很多不知道如何推 ...

  2. centos 研究

    默认工具: yum , (Ubuntu: apt-get)

  3. QT5之三大重要窗体

    当创建项目时,会发现编辑器提供三个基类,分别为:QMainWindow.QWidget.QDialog,三个基类的区别说明如下.1.QMainWindowQMainWindow类提供一个有菜单条.锚接 ...

  4. python 编码问题

    参考原文:http://www.crifan.com/eclipse_pydev_console_messy_char_for_console_is_utf8/ 通用 rq = urllib.urlo ...

  5. 2016windows(10) wamp 最简单30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world

    2016最简单windows(10) wamp 30分钟thrift入门使用讲解,实现php作为服务器和客户端的hello world thrift是什么 最简单解释 thrift是用来帮助各个编程语 ...

  6. Win 通过修改注册表把CapsLock映射为Rshift

    成品: REGEDIT4     [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] "Scancod ...

  7. 支持“ApplicationDbContext”上下文的模型已在数据库创建后发生更改

    异常信息 解决方法: 1.PM> Enable-Migrations 2.打开生成的Configuration.cs文件,修改代码如下 public Configuration() { Auto ...

  8. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

  9. struts2中的jar包

    核心包: (后面数字是版本号,不同struts2版本,数字可能不一样.) struts2-core-2.1.8.1 struts2的核心jar包,不可缺少的 xwork-core-2.1.6 xwor ...

  10. MongoDB的简单操作(asp.net)

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using MongoDB.D ...