发送长XMLHttpRequest后导航到另一个页面

时间:2012-05-17 09:42:44

标签: php javascript ajax asynchronous xmlhttprequest

我有一个XMLHttpRequest,它将大量数据插入MySQL数据库,需要5-10秒。这是请求的代码:

function sendRequest(url, params, divToChange)
{
   // code for IE7+, Firefox, Chrome, Opera, Safari
   if (window.XMLHttpRequest)
   {
       var httpRequest = new XMLHttpRequest();
   }      
   else // code for IE6, IE5
   {
       var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
   }

   // Stage 3 - open the request and prepare variables for the PHP method being  
      activated on server side//
   httpRequest.open("POST", url, true); 

   //Set request headers for POST command//
   httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   httpRequest.setRequestHeader("Content-length", params.length);
   httpRequest.setRequestHeader("Connection", "close");

   httpRequest.onreadystatechange=function()
   {
       if(httpRequest.readyState==3)
       {     
           document.getElementById(divToChange).innerHTML='please wait';
       }
       if(httpRequest.readyState==4 && httpRequest.status==200)
       {
           document.getElementById(divToChange).innerHTML=httpRequest.responseText;
       }
   }

   httpRequest.send(params); // Stage 4 - sending the request to the server//

   //end when the server will responde we will execute the        
   "document.getElementById("txtHint").innerHTML=xmlhttp.responseText;" //

}

//Calling the request with this function//
function createEventList() 
{   

   var url = "grid-update_event_list.php";
   var params = "firstLoad=1";

   //Create the httpRequest and send it to the server//
   sendRequest(url,params, "eventsList");  
}

这是在我的html中定义的,以获取回复文本:

<p>Events List Status: <b id='eventsList'>  </b></p>

我无法理解浏览器中的两种行为:

1-“请稍候”文本永远不会显示在浏览器上。当我添加alert(httpRequest.readyState)来测试正在发生的事情时,我按预期弹出了“3”,但我在readyState==3之后立即看到它readyState==4。它们似乎同时发生。我确实看到httpRequest.responseText; readyState==4中返回的文字。

2-我发送请求后无法导航到另一个页面,当前页面响应(我可以更改组合框)但是当我尝试导航到另一个链接时,浏览器等待readyState == 4然后它继续链接。我也无法理解,因为请求定义为asynchronous = true

我做错了导致这两种行为吗?感谢。

2 个答案:

答案 0 :(得分:2)

1.-你需要了解ajax调用的readystates。有5种不同的就绪状态。有关更多信息,请查看此链接:

ReadyStates

因此您可以使用不同的readystate(我会使用1或2)在请求开头显示对话框。否则只需在发送httpRequest之前更改div。

2.-即使ajax调用是异步的,它们也是顺序的。也就是说,如果您发送请求,则在收到该请求的响应之前,您无法发送另一个请求。更改页面是另一个请求/响应周期,因此在收到第一个请求的响应之前,您将无法更改页面。

希望这会有所帮助......

答案 1 :(得分:1)

我找到了这篇文章,真的很失望。我的意思是在21世纪,异步后台请求如何阻止整个浏览器进行导航?只是没有意义,现在应该已经有人修复了。

事实证明,至少在我看来,它不是浏览器。浏览器确实对并发请求的数量有限制,通常在六个附近。但这是为了防止恶意网页进行DoS攻击。真正的问题是PHP。

如果PHP使用默认的基于文件的会话系统,则该会话将被锁定,直到页面退出或对session_write_close()的调用将其关闭为止;

正在发生的事情是,基础页面打开会话,执行它的操作,然后关闭,一切都非常干净。现在,浏览器希望将某些内容AJAX放入页面的一部分,并回调到提供基础页面的同一台服务器,该服务器重新打开会话并将其保持打开状态,直到完成AJAXing。同时,页面的另一部分也希望从具有相同会话的同一服务器动态加载某些内容。 PHP说:“不,您必须等待。会话已经由另一个人打开。”一旦第一个AJAX关闭会话,第二个AJAX就会通过并完成其工作。现在,假设第一个电话需要15分钟。第二个调用以及使用同一会话到该服务器的任何链接单击都将被阻止,直到完成所有负载,单击和填充为止。恶梦!它看起来像您的页面被冻结,并且您的AJAX调用正在按顺序执行。是的,但不是因为浏览器或XmlHttpRequest。

我们该如何解决?简单的方法是击中并奔跑。如果您的页面不需要在前几行代码之后读取或写入会话,则在获取数据后,调用session_write_close()。这将解锁会话,其他人可以使用它。我正在猜测下一部分,但我认为它将起作用。如果您需要稍后写入会话,而不是保持打开状态,请关闭它以便其他人可以使用它,然后保存您的会话ID,并稍后使用session_start($ id)重新打开它。

更难的方法是编写自己的不锁定的会话处理程序。这实际上是我所做的。我有一个不锁定的基于Cassandra的会话处理程序。不利的一面是,我必须遵守“ Last in wins”的并发性,但就我而言,只有我的基本页面实际写入了会话,我的AJAX调用没有写入任何内容,因此这不是问题。如果没有锤子,就无法破坏您的数据。

希望这会有所帮助,因为虽然原始答案有助于解决我的问题,但这完全是对实际情况的误解。异步XmlHttpRequest不是顺序的。