Upgrading IIS/Classic ASP Javascript/JScript Scripting Engines (to Chakra?)

青春壹個敷衍的年華 提交于 2019-11-28 13:02:58

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() + '\n');

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

// 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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!