28

这真的让我摸不着头脑。那是因为它只发生在 IE 中,而不是 Firefox,而且我的印象是 jQuery 实际上是浏览器中立的。在过去的几个小时里,我一直在研究这件事,并且至少已经确定了正在发生的事情。

这个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 在控制器中调用了一个方法,但问题在我们做到这一点之前就出现了,所以除非有人认为它很重要,否则我不会发布该代码。发生的情况是,通常由于莫名其妙的原因,调用 PC/DeleteAssociation 的第一次 ajax 爆发返回 304(未修改)响应。我知道当什么都没有改变需要刷新时,就会发生这种情况。但这不是一个获取,它应该被视为一个帖子,我的印象是 jquery.ajax 被设计为,除非另有说明,否则不会生成 304 响应。我显然在这里遗漏了一些东西,并且盯着它看太久了,我自己也没有抓住它。有人看到我错过了什么吗?谢谢你。

4

3 回答 3

45

我看不到,您将 ajax 请求指定为 POST。所以基本上添加:

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

如果仍然失败(由于某些浏览器 AJAX 怪异),您可以尝试设置cache: false

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

顺便说一句,所有 cache: false 确实是在请求 URL 中添加一些随机内容。

编辑1:

关于

...而且我的印象是 jquery.ajax 的设计目的是,除非另有说明,否则不会生成 304 响应

jQuery istnt 在这里生成任何响应。而 304 标头只是一个 HTTP 标头。HTTP AJAX 请求是普通的 HTTP 请求,可以返回任何有效的标头。如果服务器以 304 响应,XHR 对象将简单地提供来自服务器的本地缓存响应。不过,它对用户来说是完全透明的。

编辑2:

删除了关于防止缓存的建议。对我来说似乎是巫毒教。

编辑3:

再次添加该位,因为这显然是必要的。环顾网络,IE 似乎在某种程度上非法缓存了 AJAX POST。

于 2011-03-31T15:10:58.110 回答
21
  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-两个重要事实/)。为了防止这种情况,您可以:
    1. 添加缓存破坏参数($.ajaxSetup({ cache: false });会自动执行此操作。
    2. 始终使用 POST 请求(在大多数情况下可能不合适)。
    3. 打开 AJAX 请求服务器端的缓存标头。第一个链接演示了如何在 groovy 中执行此操作。类似的方法应该适用于任何框架。
于 2012-04-05T01:57:21.493 回答
1

缓存破坏是解决方案!

在我的情况下,应用程序使用带有自定义标头的单个服务调用作为代理将浏览器桥接到服务器的私有部分(每个调用都转到相同的 url,但使用自定义标头告诉代理服务要使用哪个服务传递给)。在 Chrome 和 FF 上一切正常,但 IE 不断返回页面上第一次调用的数据。jQuery.ajax 中的 cache=false 选项是修复,因为 IE 只是查看被调用的同一个 url,甚至没有考虑是否使用了任何自定义标头,或者是否在正文中传递了不同的数据,只是说“哦,我知道这个,在这里..”并回复了第一个电话的响应。使用缓存破坏技术,url 看起来与 IE 不同,因此它通过了它。

于 2012-11-01T04:55:28.877 回答