升级IIS/经典ASP Javascript/JScript脚本引擎(至Chakra)?

3
微软表示,JavaScript现在已成为Visual Studio和“通用Windows平台”的一等公民,但我还没有找到升级IIS / Classic ASP脚本中使用的十年以上的JScript引擎的方法。因此,我的问题是,是否有人知道如何做到这一点?
为什么?
例如,在经典ASP页面(使用JavaScript而不是VBScript)中使用JSON.parse。目前,我包含了Crockford的旧json脚本的副本,这还可以,但这些天应该是不必要的。

将服务器上的IE升级到IE 11通常会有所帮助,但经典ASP是如此古老的技术。 - Lex Li
那么,有什么阻止你使用JSON.Parse的呢? - user1945782
@Lex Li:我有一个使用Win10的开发环境(因此安装了IE11和Edge),但是Classic ASP页面仍在使用旧版JScript,据我所知,我仍需要包含Crockford库。 - CodaCoder
@Paul:如果我包含第三方库,那就没问题了。关键是它不是原生的JavaScript对象和现代JavaScript引擎的实现。这就是为什么会有像aspjson这样的东西存在的原因。 - CodaCoder
2个回答

5
为什么?嗯,正如您可能知道的那样,具有Chakra的主机默认情况下未启用。根据MSDN文档
引用:

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

据我所了解,这意味着您必须编写自己的自定义脚本执行主机来使用Chakra评估现有代码。
尽管这种方法听起来很吸引人,但更容易的方法是从其他地方克隆所需的任何对象和方法。通过将htmlfile COM对象强制转换为兼容模式,可以公开当前脚本主机无法使用的对象和方法。
// 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);

完成了!现在你可以使用 JSON.parse()JSON.stringify(),而无需包含 json2.js,也无需通过调用 IActiveScript::SetProperty 来进行大量努力。

关于上面的代码片段的快速说明:在经典 JScript 中,htmlfile.write('<meta... etc />') 可以工作,但是 .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);

我还想指出,其他更现代的ECMAscript方法可以用类似的方式导入。这里有几个其他方法的演示,在JScript 5.7中不是本地可用的,但可以从IE9标准模式中的htmlfile进行克隆。将其保存为.asp扩展名并在Web浏览器中访问:
<%@ 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>

输出:

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

这是一种有趣的方法 - 可惜我无法让它正常工作。我可以从ASP中使用Server.CreateObject("htmlfile")(也尝试过ActiveXObject),但htmlfile.write会出现“htmlfile:参数无效”的错误。注意:在Visual Studio调试器中检查显示htmlfile对象已创建,并且我看到可用的write方法。 - CodaCoder
"对象不支持此属性或方法" :( - CodaCoder
我找不到任何关于 htmlfile COM 对象的文档。这个链接可能有用吗?我使用 PowerShell 来调查方法。powershell "new-object -COM htmlfile | gm | ?{ $_.Name -eq 'write' } | select -expand Definition"。要查看所有方法,可以使用 powershell "new-object -COM htmlfile | gm"。无论如何,我不知道参数有什么问题。如果将元字符串存储为变量并输出该变量,它是否正确输出,或者至少给您有关失败原因的提示? - rojo
1
也许不过我怀疑这不是语法错误,错误在于无效的参数,按照这个链接部署ASP相当简单。顺便说一下,我是在装有IIS7.5和IE11的Win7Pro盒子上进行测试的。而且说实在的,我们的应用程序有超过400K的用户,它同时使用了ASP.NET和classic,如果部署有问题,我会知道的。 - CodaCoder
显示剩余7条评论

1

将“加载用户配置文件”设置为false对我没有起作用,它会破坏整个应用程序池(可能是因为它正在使用ApplicationPoolIdentity)。

不过,对我有效的是在global.asa中像这样创建htmlfile对象:

<object runat="server" scope="application" id="JScriptHelper" progid="htmlfile"></object>
<script language="VBScript" runat="server">
Sub Application_OnStart
    JScriptHelper.write "<meta http-equiv=""x-ua-compatible"" content=""IE=9"" />"
End Sub
</script>

我不确定是不是我的配置问题,但有些功能非常慢。例如,使用lastIndexOf在一个包含60000个元素的数组中查找唯一值的位置需要5秒钟,而使用polyfill只需不到100毫秒。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接