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. bug 7715339 登录失败触发 ‘row cache lock’ 等待

    Bug 7715339 - Logon failures causes "row cache lock" waits - Allow disable of logon delay ...

  2. Javascript 6 种继承

    1.原型链继承 // 1.原型链继承的两个问题===>在借用构造函数中可以解决下下面的两个问题//problem: 在创建子类型的实例时,不能向超类型的实例传递参数(在这里就是不能向A()里传递 ...

  3. 笔记四:onsubmit和onclick的区别

    今天碰到关于表单提交的问题,我是用submit还是用onclick好呢,然后我去百度了一下两者的区别: onsubmit只能表单上使用,提交表单前会触发, onclick是按钮等控件使用, 用来触发点 ...

  4. 用py2exe打包成一个exe文件

    用py2exe打包成一个exe文件 http://blog.csdn.net/franktan2010/article/details/46514607

  5. asp.net 查询sql数据表的网页模板

    最近因为工作需求,要制作一个网页模板,主要是用于快速开发,可以查询Sql数据表信息的模板, 昨天做好了,这个只是一个Demo,但是功能已经齐全了, 开发新的网站时,需要新增一个xml,复制粘贴网页的前 ...

  6. php操作zip压缩文件

    php操作zip压缩文件 一.总结 1.php操作zip:php可以操作zip压缩文件,通过 ZZIPLIB扩展库,这些扩展库可以通过composer安装,或者某些版本的php会自带 2.完美操作zi ...

  7. 利用jquery.fullPage.js 和 scrolloverflow.min.js 实现滚屏效果

    参考链接:https://blog.csdn.net/c11073138/article/details/79631036 /* 按着思路去search. */

  8. 韦东山网课https://edu.csdn.net/course/play/207/1117

    接口讲解https://edu.csdn.net/course/play/207/1117

  9. django 简单会议室预约(2)

    --我们先打开settings.py 配置文件: import os #指明django APP目录路径 BASE_DIR = os.path.dirname(os.path.dirname(os.p ...

  10. 【例题 7-4 UVA - 524】Prime Ring Problem

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 预处理出所有的答案. 打表输出. [代码] import java.util.ArrayList; import java.util ...