【问题标题】:Upgrading IIS/Classic ASP Javascript/JScript Scripting Engines (to Chakra?)升级 IIS/经典 ASP Javascript/JScript 脚本引擎(到 Chakra?)
【发布时间】:2016-01-19 16:56:58
【问题描述】:

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

为什么?

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

【问题讨论】:

  • 将服务器上的 IE 升级到 IE 11 通常会有所帮助,但经典的 ASP 技术太老了。
  • 那么是什么阻止你使用JSON.Parse
  • @Lex Li:我有一个使用 Win10 的开发环境(因此安装了 IE11 和 Edge),但经典 ASP 页面仍在使用旧的 JScript AFAICT,我仍然需要包含 Crockford 库。
  • @Paul:没什么,如果我包含一个 3rd 方库。关键是,它不是原生 javascript 对象和现代 javascript 引擎的实现。这就是 aspjson 这样的东西存在的原因。

标签: javascript iis asp-classic jscript


【解决方案1】:

为什么?好吧,您可能知道,具有脉轮可用的主机默认情况下没有启用它。根据MSDN documentation

从 JScript 5.8 开始,默认情况下,JScript 脚本引擎支持 5.7 版中存在的语言功能集。这是为了保持与早期版本引擎的兼容性。要使用 5.8 版的完整语言功能集,Windows 脚本界面宿主必须调用 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 的巨大努力。

关于上面代码 sn-p 的简短说明:htmlfile.write('&lt;meta... etc /&gt;') 在经典 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);

我还想指出,其他更现代的 ECMAscript 方法可以以类似的方式导入。下面是一些其他方法的演示,aren't natively available in 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>

输出:

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 试试htmlfile.IHTMLDocument2_write() 方法,看看你是否有更好的运气。
  • "对象不支持该属性或方法" :(
  • 也许但我怀疑这是一个语法错误,错误是无效的 arg 并且部署 ASP 非常简单following this。 FWIW,我正在使用 IIS7.5 和 IE11 的 Win7Pro 机器上进行测试。说真的,有超过 40 万用户使用 ASP.NET 和经典的应用程序,我知道部署是否有问题。
  • 对于任何有同样问题的人,我在这里找到了解决方案:social.msdn.microsoft.com/Forums/en-US/…“我刚刚整理出来!原来这是由于站点应用程序池进程模型中的“加载用户配置文件”设置组(高级设置)。从我读到的建议是将其设置为加载用户配置文件。将其设置为 false 允许它工作并解决问题!“
【解决方案2】:

将“加载用户配置文件”设置为 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 毫秒。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2015-08-04
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多