2010-10-12 51 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

相關問題