2010-10-12 66 views
3

我有一个html页面,显示一些基本的帐户信息,并开始运行jQuery AJAX请求以检索更详细的数据。当Ajax请求正在进行时,用户可以单击具有onclick事件的按钮以使用location.assign导航到新页面。有没有办法让Internet Explorer不要等到AJAX请求完成之后才能进行链接?

不幸的是,如果在ajax请求完成之前单击该按钮,则在ajax请求完成之前不会发生任何事情。这是一个活的服务器问题。我希望用户能够立即离开。 FF和Chrome似乎表现更好,但由于这是企业内部网应用程序,因此它们不是真正的选择。

下面的代码是类似问题的网页:

  • 使用纯anchor,而不是一个:

    <html> 
        <head> 
         <script src="/js/jquery-1.3.2.min.js" type="text/javascript"> </script> 
    
         <script type="text/javascript"> 
    <!-- 
        $(function() { 
         jQuery.ajax({ 
          type: 'GET', 
          url: '/long-running-partial-html-ajax-endpoint', 
          success: function (result) { 
           $('#detail').html(result); }); 
          }, 
          error: function (xmlHttpRequest, textStatus, errorThrown) { 
           $('#detail').html('Failed to load additional information:<br />' + textStatus + '<br />' + errorThrown); 
          } 
         }); 
        }); 
    //--> 
         </script> 
        </head> 
        <body> 
         <h2>Account Information</h2> 
         <div>Some basic details here</div> 
         <div><button onclick="location.assign(&quot;/somewhere-else&quot;)" type="button">Go somewhere else now</button></div> 
         <div id="detail"> 
          <img src="/ajax-loading-animation.gif" alt="Loading ..." /> 
          Loading ... 
         </div> 
        </body> 
    </html> 
    

    事情我已经在调试器(不带电)已经尝试过脚本按钮

  • 使用xhr.abort()之前location.assign
  • alert s围绕location.assign安慰自己,代码执行时预计

观察:

  • IE停止只要点击按钮时的动画GIF。
  • FF /铬必须自动中止Ajax请求的jQuery的AJAX error事件被触发

有没有人碰到这个问题来了?你有一个解决方案,将使导航更加快速响应?

+0

您有试过锚与href(而不是'location.assign')? – 2010-10-12 14:07:21

+0

感谢您的关注Pekka。我的原始帖子中提到了一个简单的锚,这是我尝试的第一件事。 – WooWaaBob 2010-10-13 08:27:32

+0

我现在已经尝试了xhr.abort(),但是没有任何效果,除了返回的HTML没有呈现:即成功函数不会执行,这是我想的一个小胜。 – WooWaaBob 2010-10-20 10:43:12

回答

0

我结束了在服务器上的一个单独的线程中执行长时间运行的任务。然后ajax调用只需重复调用以检查响应是否已准备就绪。这样每个Ajax请求都很短。

我的解决方案适用于Intranet应用程序,但可能需要使Internet应用程序更健壮。

所以HTML变为:

<html> 
    <head> 
     <script src="/js/jquery-1.3.2.min.js" type="text/javascript"> </script> 

     <script type="text/javascript"> 
<!-- 
    var detailRequest = null; 

    function StartDetailRequest() { 
     detailRequest = jQuery.ajax({ 
      type: 'GET', 
      url: '<%= Url.Action("EnquiryDetail", "Account", new { requestGuid = ViewData["detailRequestGuid"] }) %>', 
      success: function (result) { 
       if (result.length == 0) { 
        setTimeout("StartDetailRequest()", 500); 
       } 
       else { 
        $('#detail').html(result); 
        $("table tbody").each(function() { $("tr:odd", this).addClass("odd"); }); 
       } 
      }, 
      error: function (xmlHttpRequest, textStatus, errorThrown) { 
       $('#detail').html('Failed to load additional information:<br />' + textStatus + '<br />' + errorThrown); 
      } 
     }); 
    } 

    $(function() { 
     setTimeout("StartDetailRequest()", 500); 
    }); 
//--> 
     </script> 
    </head> 
    <body> 
     <h2>Account Information</h2> 
     <div>Some basic details here</div> 
     <div><button onclick="location.assign(&quot;/somewhere-else&quot;)" type="button">Go somewhere else now</button></div> 
     <div id="detail"> 
      <img src="/ajax-loading-animation.gif" alt="Loading ..." /> 
      Loading ... 
     </div> 
    </body> 
</html> 

在服务器端,我这样做(ASP.NET MVC 2的伪代码):

private Dictionary<Guid, DetailRequestObject> detailRequestList = new Dictionary<Guid, DetailRequestObject>(); 

[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult Index(string id) 
{ 
    var model = GetTheBasicDetails(id); 
    var request = CreateDetailRequestObject(id); 

    CheckForTimedOutDetailRequests(); 

    detailRequestList.Add(request.Guid, request); 

    ViewData["detailRequestGuid"] = request.Guid; 

    return View(model); 
} 

[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult EnquiryDetail(Guid requestGuid) 
{ 
    DetailRequestObject detailRequest = detailRequestList[requestGuid]; 

    if (detailRequest == null) 
    { 
    throw new TimeoutException("Timed out retrieving details"); 
    } 
    else if (!detailRequest.IsComplete) 
    { 
    return Content(""); 
    } 
    else 
    { 
    var details = detailRequest.Response(); 

    return PartialView(details); 
    } 
} 

DetailRequestObject类封装的创建使用您选择的异步模型分离线程,完成时设置标志并收集响应数据。

我也有一个方法CheckForTimedOutDetailRequests收集已超时检索的请求,以便任何已被“中止”的可以清除。

我想我宁愿在一个单独的Windows服务运行长时间运行的请求,会做它自己的清理,请求限制等,但上述工作这么...

0

你有没有试着拨打ajax方法在页面加载

<body onload="myFunctionThatCallsAjax()"> 

有一些浏览器行为的差异,当你在HTML代码中嵌入JavaScript之后。使用onload将确保这不是一个问题。

+0

感谢您的关注ring0。我尝试了这一点,但它没有任何区别。我正在使用jQuery文档就绪函数('$(function(){});')来启动ajax请求,我相信它会达到相同的效果。 – WooWaaBob 2010-10-20 10:38:06

相关问题