XMLHttpRequest始终返回状态0的问题排查及解决
问题解析:表单提交中断AJAX请求的常见坑
哈哈,这个坑我太熟悉了!你遇到的问题根源在于表单的默认提交行为会直接中断你的AJAX请求。
为什么会出现status=0、onerror触发?
当你在<form>的onsubmit事件里调用getServiceVal()时,浏览器会同时执行两个动作:
- 启动你写的AJAX请求
- 触发表单的默认提交行为——如果表单没指定
action属性,它会尝试刷新当前页面(导航到当前URL)
这个页面刷新/导航动作会直接切断正在进行的XMLHttpRequest请求:
- 所以你会看到
readyState有时停在2(请求已发送但未完成响应)、有时勉强到4(请求被中止时的收尾状态),但status始终是0(因为请求没有正常完成,没有服务器返回的有效状态码) - 请求被强制中止会触发
onerror事件,这就是你看到错误日志的原因
两种解决办法
1. 保留表单,但阻止默认提交行为
如果你还想用表单组织输入控件,只需要在onsubmit流程里阻止浏览器的默认行为即可,有两种实现方式:
方式一:让onsubmit返回false
<form onsubmit="getServiceVal(); return false;"> <input ref="input"/> <button>Get Value</button> </form>
方式二:在函数里调用event.preventDefault()
修改你的JS函数,接收事件参数并阻止默认行为:
function getServiceVal(e) { // 阻止表单默认提交行为 if (e) e.preventDefault(); var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "/myservice?param=1"); xmlhttp.onreadystatechange=function() { console.log("--> " + xmlhttp.readyState + ", " + xmlhttp.status); if (xmlhttp.readyState==4 && xmlhttp.status==200) { console.log(xmlhttp.responseText.length); } }; xmlhttp.onerror = function(e) { console.log('There was an error! - ' + xmlhttp + ", " + e); }; xmlhttp.send(null); }
然后HTML里传递事件参数:
<form onsubmit="getServiceVal(event)"> <input ref="input"/> <button>Get Value</button> </form>
2. 使用普通按钮(你已经验证的有效方法)
像你现在这样用<input type="button">,或者给<button>明确指定type="button"(表单内的按钮默认是submit类型,会触发提交),这类按钮不会触发表单提交,AJAX请求就能正常完成:
<input type="button" value="This Button!" onclick="getServiceVal();"> <!-- 或者用button标签,明确指定type避免默认行为 --> <button type="button" onclick="getServiceVal();">Get Value</button>
内容的提问来源于stack exchange,提问作者McAviti
相关产品推荐
相关产品推荐

