2011-03-31 38 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