升级 IIS/Classic ASP Javascript/JScript 脚本引擎(到 Chakra?)

Cod*_*der 3 javascript iis asp-classic jscript

据 Microsoft 称,javascript 现在是 Visual Studio 和“通用 Windows 平台”中的一等公民,但我还没有找到一种方法来升级 IIS/Classic ASP 脚本中使用的十年前的 JScript 引擎。所以,我的问题是,有谁知道是否有办法做到这一点?

为什么?

例如,我想在经典 ASP 页面(使用 javascript 而不是 VBScript)中使用 JSON.parse。目前,我包含了 Crockford 的旧 json 脚本的副本,这还可以,但现在应该没有必要了。

roj*_*ojo 5

为什么?好吧,您可能知道,具有 Chakra 功能的主机默认情况下不会启用它。根据MSDN 文档

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

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

尽管这种拼凑听起来非常令人着迷,但从其他地方克隆您需要的任何对象和方法要容易得多。COM对象htmlfile可以公开当前脚本宿主不可用的对象和方法,只需强制其进入兼容模式即可。

// 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);
Run Code Online (Sandbox Code Playgroud)

瞧!现在您可以随心所欲地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 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);
Run Code Online (Sandbox Code Playgroud)

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

<%@ 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>
Run Code Online (Sandbox Code Playgroud)

输出:

// 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);
Run Code Online (Sandbox Code Playgroud)

  • 对于遇到同样问题的人,我在这里找到了解决方案:https://social.msdn.microsoft.com/Forums/en-US/20cfbfa5-b3ee-4337-9fc6-dd59bbf05708/htmlfilewrite-invalid-argument-on-iis- classicasp-windows-10?forum=windowsazuredevelopment “我刚刚解决了这个问题!结果发现这是由于站点应用程序池进程模型组(高级设置)中的设置“加载用户配置文件”造成的。根据我阅读的建议就是将其设置为加载用户配置文件。将其设置为 false 可以使其正常工作并解决问题!” (2认同)