【问题标题】:Proper way to handle 304 not modified in jQuery ajax处理 304 未在 jQuery ajax 中修改的正确方法
【发布时间】:2011-03-07 02:24:47
【问题描述】:

从 jQuery 1.5 开始,ajax 方法现在可以根据 XMLHTTPRequest 的 W3C 规范,通过调用 success() 处理程序正确处理 304 Not Modified 响应。这允许您的应用程序将请求视为成功,即使服务器实际上没有返回任何数据(因为您已经缓存了最新的数据)。

对于普通的(未缓存的)GET 请求,成功处理程序使用以下参数调用:

  • 数据:{来自服务器的数据}
  • 状态:正常
  • jqXHR:
    • 状态:200
    • 状态文本:正常
    • responseText:{来自服务器的数据}

对于缓存的 GET 请求,成功处理程序使用以下参数调用:

  • 数据:未定义
  • 状态:未修改
  • jqXHR:
    • 状态:304
    • 状态文本:未修改
    • responseText:{缓存中的数据}

(至少,这是它在 IOS 4.2 中返回的方式,对于通过清单文件使用应用程序缓存的 Web 应用程序。我假设这对于大多数平台/浏览器上的一般浏览器缓存是一致的)。

您可以看到“数据”参数仅在请求为 200 OK 时才被填充;其中 jqXHR.responseText 始终填充数据,无论该数据是来自服务器(200 OK)还是来自缓存(304 Not Modified)。

鉴于,在大多数 GET 请求中,您的成功处理程序都会想要对您获得的数据做一些事情,而不管它来自哪里,对于您的成功代码来说,始终使用 jqXHR 似乎是最有意义的.responseText,而不是做这样的事情:

if ("notmodified" === status) {
  // do something with jqXHR.responseText
} else {
  // do something with data
}

或者是否存在 jqXHR.responseText 不会填充到成功处理程序中,但数据 arg 的情况?

我必须检查我的代码库并更改所有成功处理程序(以前我使用的是 jQuery 1.4.2,它总是返回数据,即使是从缓存中也是如此);所以我只想确保我以正确的方式处理它。 (不想走到最后,然后意识到我应该以另一种方式完成)。

【问题讨论】:

    标签: jquery browser-cache


    【解决方案1】:

    我刚刚发现了我的问题中的明显缺陷....我假设数据始终是文本,因此使用 jqXHR.responseText 而不是 data 参数是有意义的。

    但如果数据类型为 JSON、JSONP、脚本等...如果在 304 Not Modified 响应中返回的数据未定义,则需要将 jqXHR.responseText 从字符串转换为首先是所需的类型,例如。

    if (data === undefined) {
      data = $.parseJSON(jqXHR.responseText);
    }
    

    ...您只希望在真正需要时进行这种(可能很昂贵)的转换。

    现在想想有点道理...数据总是从服务器返回(在某些情况下可能 not 对于 304 未定义...例如. 服务器可以返回一些额外的文本/html);这允许开发人员灵活地选择他们想要在 304 事件中执行的操作,例如。

    • 显示来自服务器的响应(如果有)
    • 使用 jqXHR.responseText
    • 完全做其他事情...

    【讨论】:

    • 我目前正在一个项目中处理这个问题...... jQuery 不会自动为您填充数据参数,这有点令人惊讶。我不同意你的逻辑......我很确定 HTTP 标准需要一个空的响应正文来处理 304 Not Modified 响应,所以服务器不应该发回任何额外的数据......不应该有任何歧义。
    • 在我的例子中, jqXHR.responseText 也未定义响应文本:(
    【解决方案2】:

    根据上下文,您可以在 ajax 请求中使用 cache 参数:

    $.ajax({
        url: ".....",
        dataType: "json",
        type: "GET",
            cache: false,
        contentType: "application/json",
            success: function (data, textStatus) {
                console.log("RECV: " + data);
            }
        });
    

    这对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 2017-01-07
      • 1970-01-01
      相关资源
      最近更新 更多