XMLHttpRequest 异步不起作用,总是返回状态 0
这是我从 w3schools 拼凑的 XMLHttpRequest 示例
Here's a sample XMLHttpRequest I cobbled together from w3schools
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var T="nothing";
xmlhttp=new XMLHttpRequest();
xmlhttp.overrideMimeType('text/plain'); // don't sc
xmlhttp.onreadystatechange=function()
{
alert ("rdystate: " + xmlhttp.readyState);
alert ("status: " + xmlhttp.status);
alert ("Text: " + xmlhttp.statusText);
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
T = xmlhttp.responseText;
}
}
xmlhttp.open("GET","SBL_PROBES.htm",true);
xmlhttp.send(null);
//T = xmlhttp.responseText;
alert(T);
}
</script>
</head>
<body>
<h2>Using the XMLHttpRequest object</h2>
<div id="myDiv"></div>
<button type="button" onclick="loadXMLDoc()">CHange Content</button>
</body>
</html>
XMLHttpRequest 始终返回零状态.
XMLHttpRequest always returns a zero status.
Firefox 的错误控制台中没有显示任何内容.
Nothing shows up in Firefox's error console.
如果我通过更改行将请求更改为同步请求
If I change the request to synchronous one by changing the line
xmlhttp.open("GET","SBL_PROBES.htm",true);
到
xmlhttp.open("GET","SBL_PROBES.htm",false);
并取消注释该行
//T = xmlhttp.responseText;
返回请求文件的文本.
HTM 和文件位于同一目录中.如果你尝试这个,你还需要一个文件 SBL_PROBES.htm,它的内容是无关紧要的.
The HTM and the file reside in the same directory. If you try this you will need a file SBL_PROBES.htm there also, it's contents are irrelevant.
我使用的是 Firefox 3.6.22.
I'm using Firefox 3.6.22.
这可能是跨域问题吗?如果是这样,为什么它作为同步请求工作?
Could this be a cross domain problem? If so, why does it work as a synchronous request?
推荐答案
您可以在 if 语句中使用函数.该函数在readystate变为4时执行.
You can use a function inside the if statement. This function is executed when readystate changes to 4.
var handleResponse = function (status, response) {
alert(response)
}
var handleStateChange = function () {
switch (xmlhttp.readyState) {
case 0 : // UNINITIALIZED
case 1 : // LOADING
case 2 : // LOADED
case 3 : // INTERACTIVE
break;
case 4 : // COMPLETED
handleResponse(xmlhttp.status, xmlhttp.responseText);
break;
default: alert("error");
}
}
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=handleStateChange;
xmlhttp.open("GET","SBL_PROBES.htm",true);
xmlhttp.send(null);
您的旧代码执行了异步调用,并仅使用 alert 语句继续.此时 T 为空.
Your old code did a asynchronous call and continued just with the alert Statement. T was empty at this time.
好的,我会稍微解释一下整个过程是如何工作的:
Ok, I'll explain a little bit how this whole thing works:
首先我们定义两个回调函数,我们稍后在请求中调用它们,命名为handleResponse 和handleStateChange.
First we define two callback functions, which we call later in the request, named handleResponse and handleStateChange.
然后我们创建一个对象,它代表 XMLHttpRequest
Afterwards we create a Object, which represents the XMLHttpRequest
var xmlhttp=new XMLHttpRequest();
这会产生如下的对象(简化):
This results in an Object as follows (simplyfied):
XMLHttpRequest { status=0, readyState=0, multipart=false, onreadystatechange=handleEvent()}
使用 open(...) 函数调用,您可以为请求设置参数:
With the open(...) function call you set parameters for the request:
xmlhttp.open("GET","SBL_PROBES.htm",true);
这意味着,执行异步 GET 请求来获取页面 SBL_PROBES.htm然后调用 send(...) 函数来触发请求本身.
This means, do a asynchronous GET Request to fetch the Page SBL_PROBES.htm Then the send(...) function is called which fires the request itself.
我们为onreadystatechange注册了一个回调函数,可以想象,这实际上是一个eventHandler.每次状态改变时都会调用这个函数.(这就像你在表单中注册一个回调函数到一个onKeyUp事件一样,每次你的key上升时都会触发这个回调:))
We registered a callback function for the onreadystatechange, as you can imagine, this is actually an eventHandler. Each time the state changes this function is called. (It is the same as if you register a callback function to an onKeyUp Event in a form, this callback is triggered each time your key goes up :) )
对您的问题感兴趣的唯一情况是状态 4.因此,仅在状态 4 中调用 handleRequest 回调函数.此时您的 Request 实际上有一个结果,还有一个状态.(状态表示您的网络服务器返回状态代码 200=ok、404=not found 等)
The only case which is of interest for your problem is state 4. Therefor the handleRequest callback function is called only in state 4. At this time you Request has actually a result, and further a status. (Status means your webserver returned a status code 200=ok, 404=not found etc.)
这并不是 ajax 背后的全部魔力,但应该为您提供一个简化的概述,即幕后实际发生的事情.请务必在网络服务器上进行测试,不要使用 file://进行测试.
That is not all the magic which is behind the ajax stuff, but should give you a simplified overview, what is actually happening behind the scenes. It is important that you test this on a webserver, do not use file:// for testing.
如果您需要更多详细信息,请告诉我.
If you need more in detail info, just let me know.
相关文章