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. 任务调度(四)——ScheduledExecutorService替代Timer,实现多线程任务调度

    上篇博文<任务调度(三)--Timer的替代品ScheduledExecutorService简介>已经对ScheduledExecutorService做了简介.事实上使用Schedul ...

  2. WINDOWS 安装 M2Crypto for Python2.7

    WINDOWS 安装 M2Crypto for Python2.7运行环境 WIN8.1 + Python2.7 + VS2008(Microsoft Visual C++ 9.0) VS2008 可 ...

  3. try {}里有一个return语句 finally执行顺序

    先看例子 package example; class Demo{ public static void main(String args[]) { int x=1; System.out.print ...

  4. Python数据类型中的字符串类型

    1.换行字符:\n print ('I love python.\nAnd you?') 2.转义字符(\):\\ print ('\\\n\\') 3.制表字符(对齐表格的各列):\t print ...

  5. C#调用C++生成的动态链接库DLL

    一.背景 由于要使用C#写app,所以要把C++生成的DLL在C#中调用,所以就涉及怎样去调用外部的dll问题. 二.C#调用外部DLL 首先先看下C#调用外部DLL的代码 using System. ...

  6. unity-unet-同步各个player唯一标识

    Multiplayer Game 中所有 player 都有一个唯一标识.在unet中可以通过 Network Identity 组件获取到该 player 在整个网络整的 唯一 的连接 id 这里测 ...

  7. 洛谷——P1781 宇宙总统

    https://www.luogu.org/problem/show?pid=1781 题目背景 宇宙总统竞选 题目描述 地球历公元6036年,全宇宙准备竞选一个最贤能的人当总统,共有n个非凡拔尖的人 ...

  8. @Import注解

    转自:https://blog.csdn.net/heyutao007/article/details/74994161 @Import注解就是之前xml配置中的import标签,可以用于依赖第三方包 ...

  9. 40.lombok在IntelliJ IDEA下的使用

    转自:https://www.cnblogs.com/yjmyzz/p/lombok-with-intellij-idea.html lombok是一款可以精减java代码.提升开发人员生产效率的辅助 ...

  10. JS /CSS 实现模态框(注册和登录组件)

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...