这是一个非常非常(非常!!!)奇怪的问题。
我在一个名为CSCRIPT
的文件中使用dos testJSON.js
在Windows XP和7上运行这个JSCRIPT。
if ( ! this.JSON ) WScript.Echo("JSON DOESN'T EXISTS");
而且,消息出现了,但这是JSCRIPT的意外行为,因为JSON(如MSDN documentation所说)是JSCRIPT 5.8
中的默认对象之一,而我的Windows 7系统运行完全JSCRIPT 5.8
。
现在,我通过创建一个新的文本文件并手动编写一个有效的JSON字符串来临时解决了这个问题(在一个复杂的小脚本中)(显然,即使系统没有,一切也能正常工作) JSON要求的JSCRIPT 5.8
但我主要想知道两件事:
第一为什么即使我的JSCRIPT版本支持该对象,我也无法使用JSON对象?
第二次我的JSCRIPT环境中有read something about the "enabling" of the JSON (and other) unavailable object,但所有示例都是针对C#的,我想知道是否存在一些JSCRIPT的等效代码。
答案 0 :(得分:17)
您可以使用eval()
来达到与JSON.parse()
类似的效果。
eval('obj = {' + JSONstring + '}');
之后,obj.toString()
会让您检索类似JSON.stringify()
的数据(只是没有美化选项)。 See this answer在野外举个例子。关键是,您可以从JSON文本创建对象,而无需加载任何外部库或切换解释器引擎。
这会在运行代码的工作站中引入漏洞。如果您不控制要解析的JSON的生成,或者第三方可能在其生成及其解释之间修改JSON,请考虑遵循Helen's advice。如果JSON中有不好的东西,它可能会导致你的WScript做坏事。例如,如果您的JSON字符串或文件包含以下内容:
};
var oSH = WSH.CreateObject("wscript.shell"),
cmd = oSH.Exec("%comspec%");
WSH.Sleep(250);
cmd.StdIn.WriteLine("net user pwnd password /add");
WSH.Sleep(250);
cmd.StdIn.WriteLine("net group Administrators pwnd /add");
WSH.Sleep(250);
cmd.Terminate();
var obj = {
"objName": {
"item1": "value 1",
"item2": "value 2"
}
...然后使用eval
解析它将刚刚为您的计算机添加了一个新的管理员,而没有任何视觉指示它发生。
我的建议是随意使用eval
私人或临时使用;但是对于广泛部署,请考虑包括json2.js,正如海伦建议的那样。 修改:或......
您可以通过调用htmlfile
COM对象并通过<META>
标记将其强制转换为IE9(或更高版本)兼容模式来导入JSON方法:
var htmlfile = WSH.CreateObject('htmlfile'), JSON;
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);
使用这三行,JSON对象和方法被复制到JScript运行时,允许您在不使用eval()
或下载json2.js的情况下解析JSON。你现在可以做这样的事情:
var pretty = JSON.stringify(JSON.parse(json), null, '\t');
WSH.Echo(pretty);
以下是细分:
// load htmlfile COM object and declare empty JSON object
var htmlfile = WSH.CreateObject('htmlfile'), JSON;
// force htmlfile to load Chakra engine
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
// The following statement is an overloaded compound statement, a code golfing trick.
// The "JSON = htmlfile.parentWindow.JSON" statement is executed first, copying the
// htmlfile COM object's JSON object and methods into "JSON" declared above; then
// "htmlfile.close()" ignores its argument and unloads the now unneeded COM object.
htmlfile.close(JSON = htmlfile.parentWindow.JSON);
See this answer用于其他方法(通过XHR下载json2.js,InternetExplorer.Application
COM对象,HTA混合方法和另一个htmlfile
示例。
答案 1 :(得分:9)
为什么即使我的JSCRIPT版本支持该对象,我也无法使用JSON对象?
根据MSDN,Windows脚本宿主默认使用JScript 5.7功能集来实现向后兼容。 JScript 5.8功能集仅在IE8 +标准文档模式的Internet Explorer中使用。
您有以下选择:
在您的脚本中加入json2.js。有关在JScript脚本中包含外部脚本的选项,请参阅this question。
将注册表修改为expose IE9's JScript engine to Windows Script Host。 UPD:此解决方案使用IE的JScript DLL,但不激活5.8功能集。
Create a JScript execution host programmatically使用Active Script界面并使用IActiveScriptProperty::SetProperty
强制使用JScript 5.8功能集(SCRIPTLANGUAGEVERSION_5_8
)。 Here's a C++ example
我已经阅读了关于在JSCRIPT环境中“启用”JSON(和其他)不可用对象的内容,但所有示例都是针对C#的,我想知道是否存在一些JSCRIPT的等效代码。
自定义脚本执行主机只能使用具有适当COM支持的语言创建,例如C ++,C#等.JScript不能用于此,因为,例如,它不支持输出参数。
答案 2 :(得分:0)
JSON编码,无需默认解析器即可解码:official documentation states
var $ = {};
/**
* Decode JSON
*
* @param string jsonString - JSON text
*
* @return object
*/
$.json.decode = function(jsonString) {
return (new Function("return " + jsonString)());
};
/**
* Encode JSON
*
* @param object obj - Key/Value object
*
* @return string
*/
$.json.encode = function(obj) {
var items = [];
var isArray = (function(_obj) {
try {
return (_obj instanceof Array);
} catch (e) {
return false;
}
})(obj);
var _toString = function(_obj) {
try {
if(typeof(_obj) == "object") {
return $.json.encode(_obj);
} else {
var s = String(_obj).replace(/"/g, '\\"');
if(typeof(_obj) == "number" || typeof(_obj) == "boolean") {
return s;
} else {
return '"' + s + '"';
}
}
} catch (e) {
return "null";
}
};
for(var k in obj) {
var v = obj[k];
if(!isArray) {
items.push('"' + k + '":' + _toString(v));
} else {
items.push(_toString(v));
}
}
if(!isArray) {
return "{" + items.join(",") + "}";
} else {
return "[" + items.join(",") + "]";
}
};
/**
* Test JSON
*
* @param object obj - Key/Value object
*
* @return boolean
*/
$.json.test = function(obj) {
var t1 = obj;
var t2 = $.json.encode(obj);
$.echo($.json.encode(t1));
var t3 = $.json.decode(t2);
var t4 = $.json.encode(t3);
$.echo(t4);
if(t2 == t4) {
$.echo("success");
return true;
} else {
$.echo("failed");
return false;
}
};
/**
* Echo
*
* @param string txt
*
* @return void
*/
$.echo = function(txt) {
if($.isWScript()) {
WScript.Echo(txt);
} else {
try {
window.alert(txt);
} catch (e) {
console.log(txt);
}
}
};
/**
* Check if WScript
*
* @return bool
*/
$.isWScript = function() {
return typeof(WScript) !== "undefined";
}
// test your data
var t1 = {"a": 1, "b": "banana", "c": {"d": 2, "e": 3}, "f": [100, 200, "3 hundreds", {"g": 4}]};
$.json.test(t1);