[英]Upgrading IIS/Classic ASP Javascript/JScript Scripting Engines (to Chakra?)
引用微軟的話說,JavaScript現在是Visual Studio和“通用Windows平台”的一等公民,但是我還沒有找到一種升級IIS / Classic ASP腳本中使用了十多年的JScript引擎的方法。 所以,我的問題是,有人知道是否有辦法做到這一點?
為什么?
例如,我想在經典的ASP頁中使用JSON.parse(使用javascript而不是VBScript)。 目前,我包括了Crockford的舊json腳本的副本,可以,但是現在應該沒有必要了。
為什么? 嗯,您可能知道,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
。
關於上面的代碼片段的簡短說明: htmlfile.write('<meta... etc />')
在Classic JScript中有效,但是.NET主機由於某種原因而writeln()
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擴展名保存此文件,請在網絡瀏覽器中訪問它:
<%@ 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)。
不過,對我有用的是在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只需不到100ms的時間)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.