XMLHttpRequest异步请求onreadystatechange无alert不触发问题求助
问题根源&解决方案
嘿,我一眼就看出问题所在了——表单的默认提交行为把你的异步AJAX请求给打断了!
当你点击提交按钮时,浏览器会自动触发表单的默认提交逻辑:刷新页面并发送表单请求。这时候你的异步AJAX还在后台跑呢,页面一刷新,请求直接被终止,服务器自然可能收不到请求,onreadystatechange回调也根本没机会执行。而你加的alert(url)其实是个“临时救星”——alert会阻塞浏览器的刷新流程,给AJAX足够的时间完成请求和回调,所以这时候能正常触发事件。
要保持异步实现,只需要阻止表单的默认提交行为就行,给你两种简单的修改方式:
方式一:直接在函数末尾返回false(最省事)
修改你的JavaScript代码,在发送AJAX后明确返回false,彻底阻止表单默认提交:
function collectData(){ var user = document.forms["search"]["user"].value; if (user !== ""){ var url = 'http://localhost:3000/users/'.concat('', user); var xhttp; if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari xhttp=new XMLHttpRequest(); } else{// code for IE6, IE5 xhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xhttp.onreadystatechange = function() { if (this.readyState == 4 && (this.status == 200 || this.status == 304)) { var response = JSON.parse(xhttp.responseText); alert(response.data[0].id); } }; // 可以加个错误处理,避免请求失败无提示 xhttp.onerror = function() { alert("请求失败,请检查服务器是否正常运行"); }; xhttp.open("GET", url, true); xhttp.send(); // 移除测试用的alert(url),现在不需要它阻塞页面了 return false; // 关键:阻止表单默认提交 } else { alert("Name must be filled out"); return false; } }
方式二:通过事件对象阻止默认行为(更灵活)
如果后续需要对表单事件做更多控制,可以用这种方式:
- 先修改HTML的form标签,传入事件对象:
<form name="search" onsubmit="return collectData(event)">
- 再修改JavaScript函数:
function collectData(event){ // 先阻止默认提交行为 event.preventDefault(); var user = document.forms["search"]["user"].value; if (user !== ""){ var url = 'http://localhost:3000/users/'.concat('', user); var xhttp; if (window.XMLHttpRequest){ xhttp=new XMLHttpRequest(); } else{ xhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xhttp.onreadystatechange = function() { if (this.readyState == 4 && (this.status == 200 || this.status == 304)) { var response = JSON.parse(xhttp.responseText); alert(response.data[0].id); } }; xhttp.onerror = function() { alert("请求失败,请检查服务器是否正常运行"); }; xhttp.open("GET", url, true); xhttp.send(); } else { alert("Name must be filled out"); } }
额外小建议
既然你已经引入了jQuery,其实可以用它的AJAX简化代码,兼容性更好也更简洁:
function collectData(){ var user = $("form[name='search'] input[name='user']").val(); if (user !== ""){ var url = 'http://localhost:3000/users/' + user; $.get(url, function(response) { alert(response.data[0].id); }).fail(function() { alert("请求失败,请检查服务器是否正常运行"); }); return false; } else { alert("Name must be filled out"); return false; } }
内容的提问来源于stack exchange,提问作者abeldattsun
相关产品推荐
相关产品推荐

