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. Nio学习3——基础模型:多路复用模型

    Reactor模式和NIO 本文可看成是对Doug Lea Scalable IO in Java一文的翻译. 当前分布式计算 Web Services盛行天下,这些网络服务的底层都离不开对socke ...

  2. 36.Node.js 工具模块--OS模块系统操作

    转自:http://www.runoob.com/nodejs/nodejs-module-system.html Node.js os 模块提供了一些基本的系统操作函数.我们可以通过以下方式引入该模 ...

  3. httpurlconnection发送文件到服务端并接收

    httpurlconnection发送文件到服务端并接收 客户端 import java.io.DataInputStream; import java.io.File; import java.io ...

  4. Angular:了解Typescript

    Angular是用Typescript构建的.因此在学习Angular之前有必要了解一下Typescript. [ 类型 ] Typescript增加了类型系统,好处是: 1. 有助于代码编写,预防在 ...

  5. Direct2D开发:MFC下从资源文件中加载位图

    转载请注明出处:http://www.cnblogs.com/ye-ming 0X01 概述: 相对于GDI处理界面,Direct2D有得天独厚的优势,下图就是Direct2D与GDI的效果对比,wi ...

  6. Spring入门--控制反转(IOC)与依赖注入(DI)

        1.控制反转(Inversion of Control)与依赖注入(Dependency Injection) 控制反转即IoC (Inversion of Control).它把传统上由程序 ...

  7. 对象的序列化与反序列化---IO学习笔记(四)

    对象的序列化,反序列化 对象的序列化: 就是将Object转换成byte序列 对象的反序列化: 将byte序列转换成Object 序列化流.反序列化流 序列化流(ObjectOutputStream) ...

  8. Delphi部份函数,命令,属性中文说明

    Abort 函数 引起放弃的意外处理 Abs 函数 绝对值函数 AddExitProc 函数 将一过程添加到运行时库的结束过程表中 Addr 函数 返回指定对象的地址 AdjustLineBreaks ...

  9. bootstrap课程8 bootstrap导航条在不同设备上的显示效果如何

    bootstrap课程8 bootstrap导航条在不同设备上的显示效果如何(多去看参考手册) 一.总结 一句话总结:在手机端或者平板端或者显示不够的话就缩起来了.(多去看参考手册) 二.bootst ...

  10. AVCaptureSession音频视频采集

    // // AudioVideoCaptureViewController.m // live // // Created by lujunjie on 2016/10/31. // Copyrigh ...