2011-03-31 32 views
28

這真的讓我撓了撓頭。也就是說,因爲它只發生在IE瀏覽器中,而不是Firefox,我的印象是jQuery實際上是瀏覽器中立的。過去幾個小時裏我一直在抨擊這件事,至少發現了這件事。jQuery AJAX產生304響應時它不應該

這jqGrid的:

$("#DocumentListByPartRecordsGrid").jqGrid(
      { 
      datatype: 'local',    
      colNames: ['<b>Id</b>', '<b>Document Name</b>', '<b>Document Type</b>', '<b>Effective Date</b>', '<b>Expiration Date</b>', '<b>Delete</b>'], 
      colModel: [ 
        { name: 'ASSOCIATION_ID', Index: 'ASSOCIATION_ID', resizable: true, align: 'left', hidden: true, sortable: false }, 
        { name: 'FILE_NAME', Index: 'FILE_NAME', resizable: true, align: 'left', sortable: false, width:'20%' }, 
        { name: 'DOCUMENT_TYPE', Index: 'DOCUMENT_TYPE', resizable: true, align: 'left', sortable: false, width:'20%' }, 
        { name: 'EFFECTIVE_DATE', Index: 'EFFECTIVE_DATE', resizable: true, align: 'left', sortable: false, width:'20%' }, 
        { name: 'EXPIRATION_DATE', Index: 'EXPIRATION_DATE', resizable: true, align: 'left', sortable: false, width:'20%' }, 
        { name: 'Delete', Index: 'Delete',resizable: true, align: 'center', sortable: false, width:'20%' }, 
        ],    
      rowNum: 15, 
      rowList: [15, 50, 100], 
      imgpath: '/Drm/Content/jqGrid/steel/images', 
      viewrecords: true,    
      height: 162,   
      loadui: 'block', 
      forceFit: true 
     }); 

通過此功能填充:

var mydata = '';  
<% if(!string.IsNullOrEmpty(Model.PCAssociatedDocuments)) { %>   
    var mydata = <%= Model.PCAssociatedDocuments %>; 
<% } %> 

for (var i = 0; i <= mydata.length; i++){ 
     jQuery("#DocumentListByPartRecordsGrid").addRowData(i, mydata[i], "last"); 
     } 

這是乾淨地從模型填充。這不是問題。

<a class='deleteAttachment' style='cursor: pointer;' href='#' onclick='javascript:PCDocumentDelete(" + s.AssociationId.ToString() + ", " + pcId + ");'>Delete</a> 

並調用此函數

function PCDocumentDelete(id, pcid) { 
if (confirm("Are you sure you want to delete this document?")) { 
    $.blockUI({ 
     message: "Working...", 
     css: { 
      background: '#e7f2f7', 
      padding: 10 
     } 
    }); 
    $.ajax(
     { 
      url: '/DRM/Pc/DeleteAssociation?associationId=' + id + '&pcid=' + pcid, 
      async: true, 
      dataType: "json", 
      success: function(result) { 
       if (result.Success == true) { 
        //Reload grid      
        $.ajax({ async: false }); 
        $("#DocumentListByPartRecordsGrid").setGridParam({ url: "/Drm/Pc/DeAssociatePartRecordsWithDocument?pcid=" + pcid, datatype: 'json', myType: 'GET', page: 1 }); 
        $("#DocumentListByPartRecordsGrid").trigger("reloadGrid"); 
        $.unblockUI(); 
        $.showGlobalMessage('Specified document has been successfully disassociated from this part record.'); 
       } 
       else { 
        $.unblockUI(); 
        $.showGlobalMessage('An error occurred deleting the attachment.'); 
       } 
      }, 
      error: function(res, stat) { 
       alert(res.toString()); 
       alert(stat.toString()); 
      } 
     }); 
    return false; 
} 
else { 
    return false; 
} 

}

(showGlobalMessage是創建一個內部功能:使用刪除功能,這被格式化回到控制器一樣,所以當問題出現一個特別格式化的blockUI)

ajax在控制器中調用一個方法,但問題在我們做到這一點之前就出現了,所以除非som一個人認爲這很重要,我不會發布該代碼。會發生什麼是,經常出於不可解釋的原因,第一次調用PC/DeleteAssociation的ajax突然回來了一個304(未修改)的響應。我知道發生在沒有任何變化需要刷新的情況下。但是這不是一個get,它應該被視爲一個帖子,我的印象是jquery.ajax的設計目的是,除非另有指示,否則不會生成304響應。我顯然在這裏失去了一些東西,並且一直盯着它看我自己太久了。有人看到我錯過了什麼?謝謝。

回答

43

我看不到,你指定ajax請求作爲POST。所以基本上添加:

$.ajax({ type: 'POST' }); 

,如果仍然失敗(由於一些瀏覽器的AJAX怪事),你可以嘗試設置cache: false

$.ajax({ type: 'POST', cache: false }); 

順便說一句,所有的緩存:假的呢,是加入一些隨機的東西到請求的URL。

EDIT1:

關於

...我的印象是 jquery.ajax被設計爲,除非 另有說明,否則不產生304個 反應

jQuery在此處不會生成任何響應。而304頭只是一個HTTP頭。 HTTP AJAX請求是普通的HTTP請求,可能會返回任何有效的頭文件。如果服務器以304響應,則XHR對象將簡單地提供來自服務器的本地緩存響應。不過,它對用戶來說是完全透明的。

EDIT2:

刪除了關於防止緩存的建議。對我來說就像巫毒似的。

EDIT3:

補充說,再次位,因爲它顯然是必要的。環顧網絡,IE似乎在某種程度上非法緩存AJAX POST。

+1

是。 @guildsbounty,如果你想要一個Ajax調用作爲POST,你必須明確地說; jQuery.ajax默認爲GET。它看起來有點像你調用的那個方法期待一個GET,但是,考慮到你正在傳遞它的URL參數,儘管它似乎是一個刪除操作,這似乎有點奇怪...... – 2011-03-31 15:28:32

+1

奇怪的是, Voodoo位是最後的工作。即使這個職位生成了304.我使用緩存預防,並修復它......感謝您的幫助。 – guildsbounty 2011-03-31 17:28:11

+0

@guildsbounty::d怪。我環顧了一下,IE似乎真的有問題。重新編輯它。感謝您的反饋! – skarmats 2011-03-31 17:43:17

20
  1. 始終使用POST調用修改狀態的方法,而不是GET。在這種情況下,這應該足以阻止IE緩存請求。
  2. IE積極緩存ajax請求(請參閱http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/https://blog.httpwatch.com/2009/08/07/ajax-caching-two-important-facts/)。爲了防止出現這種情況,您可以:
    1. 添加緩存清除參數($.ajaxSetup({ cache: false });自動執行此操作。
    2. 始終使用POST請求(在大多數情況下可能不適用)。
    3. 打開AJAX請求服務器端的緩存標頭。第一個鏈接演示瞭如何在groovy中使用它。類似的方法應適用於任何框架。
+0

使用$ .load()方法時,設置全局ajax參數可解決相同的問題。 – lhoess 2012-12-28 23:04:48

+3

*打開AJAX請求服務器端的緩存頭* - 'Cache-Control:no-cache'或'Expires:-1'代表像我這樣懶惰的人。 – ulidtko 2013-12-23 17:53:13

0

Cache busting是解決方案!

在我的情況下,應用程序使用一個自定義標頭的服務調用作爲代理將瀏覽器連接到服務器的私有部分(每個調用都轉到同一個url,但使用自定義標頭來告訴代理服務將哪個服務傳遞給它)。在Chrome和FF上一切運行良好,但IE不停地從頁面上的第一個調用返回數據。 jQuery.ajax中的cache = false選項是修復的,因爲IE只查看了被調用的相同url,甚至沒有考慮是否使用了任何自定義標頭,或者是否有不同的數據甚至在body中傳遞,說:「哦,我知道這個,在這裏......」,並回復了第一個電話的迴應。隨着緩存清除技術的URL看起來不同的IE瀏覽器,所以它發送。

+0

HTTP緩存控制也可以解決您的問題。 – ulidtko 2013-12-23 17:54:41