server端运行JS代码

话说,当今不在client使用JS代码才是稀罕事.因为web应用的体验越来越丰富,client用JS实现的逻辑也越来越多,这造成的结果就是某些差点儿一致的逻辑须要在client和服务端各实现一遍,大牛们当然不甘心啊!幸运的是,我们能够在server端运行JS代码,谁让JS抱了一根大腿呢...

比如,现在在client使用JS进行验证已经是个标准,他能够有效避免用户在正常情况下提交错误的数据,增强用户体验.当然,server端的验证也是不可缺少的,由于这才是安全性的体现.有些解决方式,,会在server端提供优先的验证种类,然后在client生成JS代码,并辅助以server端的验证框架.这样的做法能够追溯到ASP.NET上的一个控件,但这显然会有扩展性,灵活性上的限制,因此都比較倾向与server端运行JS代码.

比如,要检查username是否合法,我们可能这样写代码:

var checkName=function (name){return /^\w{3,10}$/.test(name);

}

这在client验证自然没有不论什么问题,server端就要借助一些JavaScript运行引擎了。在.NET平台上有比如比較新的IronJS项目,这是个基于DLR的JavaScript运行引擎,十分重视性能。从作者博客上的评測结果来看。甚至率先于以速度见长的V8。

可惜的是,IronJS还没有完整实现ECMAScript 3.0。还缺少一些重要功能。比如正則表達式。

Jint是一个.NET平台上较早的JavaScript运行引擎,因此与DLR关系不大,因此可能不太easy与IronPython。IronRuby等语言进行互操作。用它来运行一些简单的JavaScript脚本不成问题,比如上面的代码:

var jint = new Jint.JintEngine();jint.Run(@"var checkName = function(name) { return /^\w{3,10}$/.test(name); }");Console.WriteLine(jint.CallFunction("checkName", "jeffz")); // TrueConsole.WriteLine(jint.CallFunction("checkName", "hello world")); // False

仅仅可惜,在实际使用中,Jint不支持多线程的环境。即我们无法在多个线程下同一时候调用jint的CallFunction方法,可是假设每次都又一次Run一遍JavaScript代码,也会带来较多的性能开销。事实上要解决问题也并不困难,构造一个对象池就可以,.NET 4中提供了并行容器(如ConcurrentStack,ConcurrentQueue),实现一个简单的对象池可谓不费吹灰之力。

这方面Jurassic的表现要好的多。这是一个构建于.NET 4.0的JavaScript运行引擎:

var engine = new Jurassic.ScriptEngine();engine.Evaluate(@"var checkName = function(name) { return /^\w{3,10}$/.test(name); }");Console.WriteLine(engine.CallGlobalFunction<bool>("checkName", "jeffz"));Console.WriteLine(engine.CallGlobalFunction<bool>("checkName", "hello world"));

此外,从Benchmark上来看,Jurassic性能也比Jint有所提高。但还是远远落后于V8。甚至IE 8里的JavaScript引擎。并且。它还提供了一个基于Silverlight控制台,您能够在浏览器里把玩一番。

令人感到意外的是。Jint和Jurassic作为JavaScript执行引擎都有一些严重的问题,那便是不能正确执行showdown.js(JavaScript实现的Markdown转化器)——尽管我并没有发现showdown.js中有过于复杂的内容,基本就是些字符串操作吧。

原本我还想把它们用在mono中,既然如此也就不做进一步尝试了。只是。经过简单的实验。Jurassic似乎使用了mono 2.8中尚不支持的接口,但也有可能仅仅是Jurassic控制台中的问题。

有趣的是,.NET平台下最靠谱的JavaScript运行引擎竟然是Rhino JavaScript,近期一次公布是在2009年3月,只是实现的十分完整。要说缺点,可能就是使用起来比較麻烦,还有。这是个Java项目。

嗯,我没有开玩笑,我们全然能够在.NET平台下使用Rhino JavaScript:

var cx = Context.enter();try{    var scope = cx.initStandardObjects();    cx.evaluateString(scope, @"var checkName = function(name) { return /^\w{3,10}$/.test(name); }", "checkName.js", 1, null);    var func = (Function)scope.get("checkName", scope);     Console.WriteLine(Context.toString(func.call(cx, scope, scope, "jeffz")));    Console.WriteLine(Context.toString(func.call(cx, scope, scope, "hello world"));}finally {    Context.exit();}

由于我们有IKVM.NET。mono等.NET开源社区上有大量宝藏。就看您能利用多少了。

我用ikvmc把js.jar转化为RhinoJs.dll之后就能够直接使用,效果非常好,对调试也有非常好的支持(假设JavaScript运行时出现了错误。则VS会直接带您至出错的那行)。

性能也是比較令人惬意的。在我的Mac OSX上安装的Ubuntu Server 10.10虚拟机。单线程转化并过滤博客上近期的3800条评论,大约耗时20秒。试验时Host上还开着一个Windows 7虚拟机,还有大量浏览器等应用程序,并不十分空暇。

您可能知道,我的博客眼下是基于mono 2.6的,当中比較有特色的地方便是评论功能了。我使用Markdown标记,并提供了实时的预览功能,这自然须要在client解释Markdown标记,并进行过滤。

眼下。我还在server使用了C#实现的Markdown转化器及过滤逻辑,但在某些特殊情况下结果会有所不同,且须要维护两套代码。不久以后。我会将把博客升级为ASP.NET 4.0及mono 2.8(C# 4.0的dynamic特性在某些情况下的确比較方便)。而且在server端使用IKVM.NET + Rhino JavaScript运行同样转化代码。从效果上来看还是十分令人惬意的。

值得一提的是,事实上在.NET平台上另一个基于DLR的JavaScript运行引擎,是为RemObjects Script for .NET,据称也支持mono。仅仅可惜它并非开源产品(只是公开了源码),且授权协议要求我们最多在5台机器上安装代码。且仅仅供我们自己使用,于是我就没有对它有关注太多了。

JS的第一部分完事了,本来第二部分还是想依照书上的指示下下去,发现没啥意思.

我想这是写点关于设计模式的东西,还是那句话,写程序不是计算机技术,要掌握一点原理性的东西还有思想上的东西.

大三一年不准备学代码了,学原理,学思想!

JS学习十四天----server端运行JS代码的更多相关文章

  1. Node.js学习笔记(1):Node.js快速开始

    Node.js学习笔记(1):Node.js快速开始 Node.js的安装 下载 官方网址:https://nodejs.org/en/ 说明: 在Windows上安装时务必选择全部组件,包括勾选Ad ...

  2. js上 十四、对象

    十四.对象 #1.初识对象 什么是对象? 在js中,一切皆是对象. 对象,生活中可见和不可见的东西,在世界中,客观存在的都是一个对象. 桌子,笔记本,手机,人. 在日常生活中,我们是如何来描述这个对象 ...

  3. 强化学习(十四) Actor-Critic

    在强化学习(十三) 策略梯度(Policy Gradient)中,我们讲到了基于策略(Policy Based)的强化学习方法的基本思路,并讨论了蒙特卡罗策略梯度reinforce算法.但是由于该算法 ...

  4. Scala学习十四——模式匹配和样例类

    一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...

  5. Spring学习(十四)----- Spring Auto Scanning Components —— 自动扫描组件

    一.      Spring Auto Scanning Components —— 自动扫描组件 1.      Declares Components Manually——手动配置componen ...

  6. JVM学习十四 - (复习)类文件结构

    类文件结构 JVM 的"无关性" 谈论 JVM 的无关性,主要有以下两个: 平台无关性:任何操作系统都能运行 Java 代码 语言无关性: JVM 能运行除 Java 以外的其他代 ...

  7. Vue.js 学习笔记 第1章 初识Vue.js

    本篇目录: 1.1 Vue.js 是什么 1.2 如何使用Vue.js 本章主要介绍与Vue.js有关的一些概念与技术,并帮助你了解它们背后相关的工作原理. 通过对本章的学习,即使从未接触过Vue.j ...

  8. 前端学习(十四)js回顾和定时器(笔记)

    回顾知识点:    作用域:        1.全局变量:在任何位置都可以使用的变量        2.局部变量:只能在函数内部使用的变量        3.闭包:子函数可以使用父函数的局部变量 -- ...

  9. js学习(四)

    一.typeof 操作符,null, undefinde 1. typeof 操作符来检测变量的数据类型. typeof "John" // 返回 string typeof 3. ...

随机推荐

  1. 更为详细的Txtsetup.sif文件解释

    更为详细的Txtsetup.sif文件解释;代码页定义, 以免文本安装模式下无法正常显示简体中文 (以下基本都是跟简体中文相关的, 不同语言版本的 Windows, 此处定义也不同)[nls]Ansi ...

  2. Eclipse-ERROR

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-c ...

  3. Activity学习

    http://www.360doc.com/content/13/1106/11/203871_327110236.shtml http://www.jianshu.com/p/e6971e8a8da ...

  4. activity-栈相关属性

    1.启动任务栈 第一种,动作设置为“android.intent.action.MAIN”,类别设置为“android.intent.category.LAUNCHER”,可以使这个ACT(activ ...

  5. Vue 使用use、prototype自定义自己的全局组件

    使用Vue.use()写一个自己的全局组件. 目录如下: 然后在Loading.vue里面定义自己的组件模板 <template> <div v-if="loadFlag& ...

  6. 00091_字符输入流Reader

    1.字符输入流Reader (1)字符输入流Reader我们读取拥有中文的文件时,使用的字节流在读取,那么我们读取到的都是一个一个字节: (2)只要把这些字节去查阅对应的编码表,就能够得到与之对应的字 ...

  7. 【Educational Codeforces Round 33 A】Chess For Three

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟题.知道哪个人是旁观者就好 [代码] /* 1.Shoud it use long long ? 2.Have you ever ...

  8. DB2 概览

    2006:IBM公布DB2.9.将数据库领域带入XML时代.IT建设业已进入SOA(Service-Oriented Architecture)时代.实现SOA.其核心难点是顺畅解决不同应用间的数据交 ...

  9. sshfs 通过ssh 挂载远程目录

    安装:yum -y install sshfs 挂载远程 ssh 文件系统: sshfs -p 1234 root@192.168.1.218:/home/ /mnt/ sshfs -p SSH端口 ...

  10. Fiddler--功能简介

    Fiddler的基本介绍 Fiddler的官方网站:  www.fiddler2.com Fiddler官方网站提供了大量的帮助文档和视频教程, 这是学习Fiddler的最好资料. Fiddler是最 ...