通过VBScript的XMLHttpRequest调用网页时JavaScript无法执行
问题:VBScript调用ASP Classic页面无实际操作,JS轮询逻辑未执行
场景概述
我实现了一套轮询流程:
- 通过VBScript发起XMLHttpRequest请求ASP Classic页面
- ASP页面负责检查MSSQL表的新增记录,调用API将用户添加至Azure AD
- 浏览器加载页面时功能正常,但直接运行VBScript或通过Windows任务计划执行(返回0x0执行成功)都无实际操作,推测是
default()函数中的JavaScript未执行,导致createADAccount()未运行
相关代码
VBScript代码
set xmlhttp = createobject("microsoft.xmlhttp") xmlhttp.open "GET", "https://myserver.com/polling.asp?route=create-ad-account", false xmlhttp.send set xmlhttp = nothing
ASP Classic代码
... action = request("action") route = request("route") openDB() select case action case "create-ad-account" : createADAccount() case else : default() end select closeDb() ... function createADAccount() ''Checks table for new records, add to AD accordingly. ... end function function default() %> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> //Get route var route = getUrlVars()["route"]; //Autorun if(route!=''){ doPoll('?action=' + route); } function doPoll(url) { var result; $.post(url, function(data) { result = data; }) .done(function (){ console.log(result); //Show results here if(result!=''){ setTimeout(doPoll(url),1000); } else { console.log('Task competed'); } }) .fail(function (jqXHR, textStatus, errorThrown){ console.log('Error: ' + textStatus); }) } function getUrlVars(){ var vars = [], hash; var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars.push(hash[0]); vars[hash[0]] = hash[1]; } return vars; } </script> <% end function
问题诊断
VBScript中的Microsoft.XMLHTTP是纯HTTP客户端,仅会接收ASP返回的HTML/JS文本,但不会像浏览器一样解析并执行JavaScript代码。浏览器中能正常工作是因为浏览器会渲染页面并触发内嵌JS的执行,而VBScript仅获取响应内容,无法触发JS里的doPoll及后续POST请求,自然不会调用到createADAccount()。
解决方案
方案1:直接修改VBScript,触发服务器端逻辑
既然ASP通过action参数调用createADAccount(),可直接让VBScript请求带action参数的地址,跳过JS中间层:
' POST方式(推荐) set xmlhttp = createobject("microsoft.xmlhttp") xmlhttp.open "POST", "https://myserver.com/polling.asp", false xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" xmlhttp.send "action=create-ad-account" set xmlhttp = nothing ' 或GET方式 set xmlhttp = createobject("microsoft.xmlhttp") xmlhttp.open "GET", "https://myserver.com/polling.asp?action=create-ad-account", false xmlhttp.send set xmlhttp = nothing
方案2:重构ASP页面,分离业务逻辑与前端展示
将轮询的业务逻辑(检查MSSQL、调用Azure AD API)完全放在ASP服务器端,不依赖前端JS:
... action = request("action") route = request("route") openDB() select case action case "create-ad-account" : ' 直接执行轮询逻辑,直到无新增记录 handlePolling() case else : default() end select closeDb() ... function createADAccount() ''Checks table for new records, add to AD accordingly. ' 返回是否还有待处理记录(有则返回True,无则返回False) ... end function function handlePolling() do while true hasMore = createADAccount() if not hasMore then exit do end if ' 服务器端延迟1秒,模拟JS的setTimeout WScript.Sleep 1000 ' IIS环境下若无法使用WScript,可替换为循环等待逻辑 loop end function function default() %> <!-- 保留原前端JS代码,供浏览器访问使用 --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> var route = getUrlVars()["route"]; if(route!=''){ doPoll('?action=' + route); } function doPoll(url) { var result; $.post(url, function(data) { result = data; }) .done(function (){ console.log(result); if(result!=''){ setTimeout(function(){ doPoll(url); },1000); // 修复原代码立即执行的问题 } else { console.log('Task completed'); } }) .fail(function (jqXHR, textStatus, errorThrown){ console.log('Error: ' + textStatus); }) } function getUrlVars(){ var vars = [], hash; var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars.push(hash[0]); vars[hash[0]] = hash[1]; } return vars; } </script> <% end function
方案3:用Windows Script Host执行JScript(复用JS逻辑)
若坚持复用JS轮询逻辑,可改用WSH执行JScript模拟HTTP请求:
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); function doPoll(url) { xmlhttp.open("POST", "https://myserver.com/polling.asp" + url, false); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlhttp.send(); var result = xmlhttp.responseText; WScript.Echo(result); if (result != '') { WScript.Sleep(1000); doPoll(url); } else { WScript.Echo('Task completed'); } } // 触发轮询 doPoll('?action=create-ad-account');
保存为.js文件后,用任务计划执行wscript.exe yourscript.js即可。
内容的提问来源于stack exchange,提问作者Benzine
相关产品推荐
相关产品推荐

