繁体   English   中英

XMLHttpRequest异步不起作用,总是返回状态0

[英]XMLHttpRequest asynchronous not working, always returns status 0

这是我从w3schools拼凑而成的XMLHttpRequest示例

<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始终返回零状态。

Firefox的错误控制台中没有显示任何内容。

如果我通过更改行将请求更改为同步请求

xmlhttp.open("GET","SBL_PROBES.htm",true);

xmlhttp.open("GET","SBL_PROBES.htm",false);

并取消评论该行

//T = xmlhttp.responseText;

将返回所请求文件的文本。

HTM和文件位于同一目录中。 如果你试试这个,你还需要一个文件SBL_PROBES.htm,它的内容是无关紧要的。

我正在使用Firefox 3.6.22。

这可能是跨域问题吗? 如果是这样,为什么它作为同步请求工作?

您可以在if语句中使用函数。 当readystate更改为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空了。

好的,我会解释一下这整个过程是如何工作的:

首先,我们定义两个回调函数,我们稍后在请求中调用它们,名为handleResponse和handleStateChange。

然后我们创建一个Object,它代表XMLHttpRequest

var xmlhttp=new XMLHttpRequest();

这导致一个Object如下(简单):

XMLHttpRequest { status=0, readyState=0, multipart=false, onreadystatechange=handleEvent()}

使用open(...)函数调用,您可以为请求设置参数:

xmlhttp.open("GET","SBL_PROBES.htm",true);

这意味着,执行异步GET请求以获取页面SBL_PROBES.htm然后调用send(...)函数来激活请求本身。

我们为onreadystatechange注册了一个回调函数,你可以想象,这实际上是一个eventHandler。 每次状态改变时,都会调用此函数。 (这与在表单中向onKeyUp事件注册回调函数相同,每次键上升时都会触发此回调:))

唯一对你的问题感兴趣的情况是状态4.因此,只在状态4中调用handleRequest回调函数。此时你的Request实际上是一个结果,还有一个状态。 (状态表示您的网络服务器返回状态代码200 = ok,404 =未找到等)

这不是ajax背后的所有魔力,但应该给你一个简化的概述,幕后实际发生的事情。 在Web服务器上测试它非常重要,不要使用file://进行测试。

如果您需要更多详细信息,请告诉我。

状态为零有两个原因。

  1. 您正在运行文件协议。
  2. 当Ajax请求处于活动状态时,有些东西会回发页面。

我相信你在这里看到#2。 所以你需要取消按钮点击。

<button type="button" onclick="loadXMLDoc(); return false;">CHange Content</button>

在你的代码,警报(T)上面总是会说什么时,请求是异步的。

这是因为异步在请求返回之前返回。 请求返回后,同步请求将返回。

尝试在这里操纵你的逻辑。

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;
      alert(T);
    }
  }

我在使用异步XMLHttpRequest open语句时遇到了无法获得结果的问题。 由于这个问题是我在使用谷歌时发现的第一个问题,以下是我如何解决它:

如果使用表单内的按钮,请确保将其设置为type =“submit”和onclick =“return myFunction()”。 在myFunction()中,请确保返回false, 而不是 true! 通过从函数返回true,您重新加载页面,XML对象消失。 如果返回false,则XML请求将获得完成所需的时间并运行onreadystatechange函数。

来源: Flask邮件列表

我现在收到了对这个常见问题的良好回应。 回应如下:

在开发Web时,这是一个非常常见的问题。 它有两种方法。

  1. 第一种是使用JSONP,我们的API在您添加查询参数(“?callback = foo”)时支持。 这应该让您立即启动并运行,非常适合开发,但由于用户可以访问您的API密钥,因此无法安全地用于生产。
  2. 第二个(我们在预测中使用的,也是最好的生产方法)是在您自己的域上设置代理服务器,代表用户提出预测请求。 这会避开浏览器的同源策略,阻止用户访问您的API密钥(可以存储在服务器端),并且还允许您根据需要使用请求缓存。 (我们最喜欢的网络服务器NGINX支持开箱即用,非常容易配置。如果您需要一些示例配置,请告诉我们!)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM