2009年1月29日星期四

WSH中XMLHttp的怪异表现

参考如下JScript代码:

var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
xmlhttp.onreadystatechange = function () {
 WScript.Echo(xmlhttp.readyState);
}
xmlhttp.open("GET", "http://otnth.blogspot.com/", true);
xmlhttp.send();

保存为js文件并用cscript或wscript执行,上述程序输出两次1后退出。如果把open挪到onreadystatechange前面,则只输出一次1后退出。

网上有很多人遇到移步方式下onreadystatechange只执行一次的问题,解决办法是把onreadystatechange写在open前面。但这里的问题似乎没有那么简单,感觉像是Windows Scripting Host脚本宿主未等待onreadystatechange变化就直接退出了,于是我写了如下代码求证:

var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
xmlhttp.open("GET", "http://otnth.blogspot.com/", true);
xmlhttp.send();
while (true) {
 var n = xmlhttp.readyState;
 WScript.Echo(n);
 WScript.Sleep(100);
 if (n == 4) break;
}

这次输出了N个1后,直接跳到4。所以,WSH是单线程的?

解决问题的办法也有,即使用WScript.Shell新开一个进程运行所需代码,并通过命令行传递参数:

if (WScript.Arguments.length>0) {
 var xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");
 xmlhttp.open("GET", WScript.Arguments.item(0), false);
 xmlhttp.send();
 WScript.Echo(xmlhttp.status + ' : ' + xmlhttp.statusText);
} else {
 var wsh = new ActiveXObject("WScript.Shell");
 var s = 'http://otnth.blogspot.com/';
 wsh.run('wscript ' + WScript.scriptfullname + ' "' + s + '"');
}

能用,不过看起来很不舒服。另外需要注意的是,命令行参数有长度限制,还要留意引号的问题。

好吧,就这样了。

没有评论 :