Microsoft的说法是,javascript现在是Visual Studio和“ Universal Windows平台”的一等公民,但我还没有找到升级IIS / Classic ASP脚本中使用了十多年的JScript引擎的方法。所以,我的问题是,有人知道是否有办法吗?
为什么?
例如,我想在经典的ASP页面(使用JavaScript而不是VBScript)中使用JSON.parse。目前,我包括了Crockford的旧json脚本的副本,可以,但是现在应该没有必要了。
为什么?嗯,您可能知道,Chakra可用的主机默认情况下未启用它。根据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
的巨大工作。
关于上面的代码片段的简短说明:htmlfile.write('<meta... etc />')
在Classic 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
将“ Load User Profile”设置为false对我不起作用,它破坏了整个应用程序池(可能是因为它正在使用ApplicationPoolIdentity)。