升级 IIS/经典 ASP Javascript/JScript 脚本引擎(到 Chakra?) [英] Upgrading IIS/Classic ASP Javascript/JScript Scripting Engines (to Chakra?)

查看:15
本文介绍了升级 IIS/经典 ASP Javascript/JScript 脚本引擎(到 Chakra?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

引用微软的话说,javascript 现在是 Visual Studio 和通用 Windows 平台"中的一等公民,但我还没有找到一种方法来升级在 IIS/Classic ASP 脚本中使用的十年以上的旧 JScript 引擎.所以,我的问题是,有没有人知道是否有办法做到这一点?

为什么?

例如,我想在经典的 ASP 页面(使用 javascript 而不是 VBScript)中使用 JSON.parse.目前,我包含了 Crockford 的旧 json 脚本的副本,这很好,但这些天应该是不必要的.

解决方案

为什么?好吧,正如您可能知道的那样,默认情况下没有启用 Chakra 的主机.根据 MSDN 文档:><块引用>

从 JScript 5.8 开始,默认情况下,JScript 脚本引擎支持 5.7 版中存在的语言功能集.这是为了保持与早期版本引擎的兼容性.要使用 5.8 版的完整语言功能集,Windows 脚本接口主机必须调用 IActiveScriptProperty::SetProperty.

据我所知,这意味着您必须编写自己的自定义脚本执行主机,才能使用 Chakra 评估现有代码.-_-

这种混搭听起来非常迷人,但从其他地方克隆您需要的任何对象和方法要容易得多.htmlfile COM 对象可以公开当前脚本宿主不可用的对象和方法,只需将其强制为兼容模式即可.

//经典WSH JScript 版本var htmlfile = new ActiveXObject('htmlfile'), JSON;htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9"/>');htmlfile.close(JSON = htmlfile.parentWindow.JSON);

瞧!现在你可以JSON.parse()JSON.stringify() 直到你心满意足,无需包含 json2.js,也无需付出巨大的努力调用 IActiveScript::SetProperty.

关于上述代码片段的简短说明:htmlfile.write('<meta... etc/>') 在经典 JScript 中工作,但 .NET 主机在 write()writeln() 方法出于某种原因.如果您切换到 .aspx 和 JScript.NET,则应改用 IHTMLDocument2_write()IHTMLDocument2_writeln().

//JScript.NET 版本var htmlfile:Object = new ActiveXObject('htmlfile'), JSON:Object = {};htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9"/>');htmlfile.close(JSON = htmlfile.parentWindow.JSON);

我还想指出其他更现代的 ECMAscript 方法可以以类似的方式导入.这是一些其他方法的演示,t 在 JScript 5.7 中本机可用,但可以在 IE9 标准模式下从 htmlfile 克隆.使用 .asp 扩展名保存它,在您的网络浏览器中访问它:

<%@ Language="JScript" %><h3>输出:</h3><textarea style="宽度:100%;高度:5em"><%var htmlfile = Server.CreateObject('htmlfile');htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9"/>');//从 htmlfile 中公开更现代的方法var JSON = htmlfile.parentWindow.JSON;String.prototype.trim = htmlfile.parentWindow.String.prototype.trim;Array.prototype.indexOf = htmlfile.parentWindow.Array.prototype.indexOf;Array.prototype.forEach = htmlfile.parentWindow.Array.prototype.forEach;Object.keys = htmlfile.parentWindow.Object.keys;htmlfile.close();//不再需要//演示 JSON.parse() 和 String.trim()var strJSON = '{ "item1": " val1 需要修剪." }';var objFromJSON = JSON.parse(strJSON);Response.Write('JSON and String.trim() 演示结果:' + objFromJSON.item1.trim() + '
');//演示 Array.indexOf()var arr = [2, 4, 6, 8, 10];Response.Write('Array.indexOf(val) 演示结果:' + arr.indexOf(4) + '
');//演示 Object.keys() 和 Array.forEach()var demo = { "foo": "bar", "baz": "qux" };demo.getKey = function(val) {var obj = 这个,结果;Object.keys(obj).forEach(function(i) {if (obj[i] === val) 结果 = i;});返回结果;}Response.Write('Object.keys(obj).forEach(fn) 演示结果:' + demo.getKey('qux'));%></textarea>

输出:

JSON 和 String.trim() 演示结果:val1 需要修剪.Array.indexOf(val) 演示结果:1Object.keys(obj).forEach(fn) 演示结果:baz

Microsoft are quoted as saying that javascript is now a first class citizen in Visual Studio and the "Universal Windows platform" but I have yet to find a way of upgrading the decade+ old JScript engine used in IIS/Classic ASP script. So, my question is, does anyone know if there is a way to do this?

Why?

I'd like to use JSON.parse, for example, in a classic ASP page (that uses javascript not VBScript). Currently, I'm including a copy of Crockford's old json script which is okay but these days should be unnecessary.

解决方案

Why? Well, as you probably know, hosts with Chakra available don't have it enabled by default. According to MSDN documentation:

Starting with JScript 5.8, by default, the JScript scripting engine supports the language feature set as it existed in version 5.7. This is to maintain compatibility with the earlier versions of the engine. To use the complete language feature set of version 5.8, the Windows Script interface host has to invoke IActiveScriptProperty::SetProperty.

From what I've been able to understand, this means you'd have to code your own custom script execution host to evaluate your existing code with Chakra. -_-

As thoroughly enthralling as such a kludge sounds, it's much easier to clone whatever object and methods you need from elsewhere. The htmlfile COM object can expose objects and methods not available to the current script host, simply by forcing it into a compatibility mode.

// classic WSH JScript version
var htmlfile = new ActiveXObject('htmlfile'), JSON;
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);

And voila! Now you can JSON.parse() or JSON.stringify() till your heart's content, without having to include json2.js, and without having to go through the enormous effort of invoking IActiveScript::SetProperty.

A quick note about that code snippet above: htmlfile.write('<meta... etc />') works in Classic JScript, but .NET hosts struggle with the write() and writeln() methods for some reason. IHTMLDocument2_write() and IHTMLDocument2_writeln() should be used instead if you ever switch to .aspx and JScript.NET.

// JScript.NET version
var htmlfile:Object = new ActiveXObject('htmlfile'), JSON:Object = {};
htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);

I'd also like to point out that other more modern ECMAscript methods can be imported in a similar way. Here's a demo of a few other methods that aren't natively available in JScript 5.7 but can be cloned from htmlfile in IE9 standards mode. Save this with an .asp extension visit it in your web browser:

<%@ Language="JScript" %>
<h3>Output:</h3>
<textarea style="width: 100%; height: 5em"><%
var htmlfile = Server.CreateObject('htmlfile');
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');

// expose more modern methods from htmlfile
var JSON = htmlfile.parentWindow.JSON;
String.prototype.trim = htmlfile.parentWindow.String.prototype.trim;
Array.prototype.indexOf = htmlfile.parentWindow.Array.prototype.indexOf;
Array.prototype.forEach = htmlfile.parentWindow.Array.prototype.forEach;
Object.keys = htmlfile.parentWindow.Object.keys;

htmlfile.close(); // no longer needed

// demonstrate JSON.parse() and String.trim()
var strJSON = '{ "item1": "          val1 needs trimmed.          " }';
var objFromJSON = JSON.parse(strJSON);
Response.Write('JSON and String.trim() demo result: ' + objFromJSON.item1.trim() + '
');

// demonstrate Array.indexOf()
var arr = [2, 4, 6, 8, 10];
Response.Write('Array.indexOf(val) demo result: ' + arr.indexOf(4) + '
');

// demonstrate Object.keys() and Array.forEach()
var demo = { "foo": "bar", "baz ": "qux" };
demo.getKey = function(val) {
    var obj = this, result;
    Object.keys(obj).forEach(function(i) {
        if (obj[i] === val) result = i;
    });
    return result;
}
Response.Write('Object.keys(obj).forEach(fn) demo result: ' + demo.getKey('qux'));
%></textarea>

Output:

JSON and String.trim() demo result: val1 needs trimmed.
Array.indexOf(val) demo result: 1
Object.keys(obj).forEach(fn) demo result: baz

这篇关于升级 IIS/经典 ASP Javascript/JScript 脚本引擎(到 Chakra?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆