如何检查 jQuery.ajax() 请求头状态是否为“304 Not Modified"? [英] How to check if jQuery.ajax() request header Status is "304 Not Modified"?

查看:83
本文介绍了如何检查 jQuery.ajax() 请求头状态是否为“304 Not Modified"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何检查jQuery.ajax() 请求头状态是否为304 Not Modified"?

How to check if jQuery.ajax() request header Status is "304 Not Modified"?

jqXHR.status 通常返回 200,即使请求的标头是304 Not Modified".

jqXHR.status usually returns 200, even when requested header is "304 Not Modified".

ifModified:true 没有多大帮助,因为它破坏了 XHR 数据请求.

ifModified:true does not help a lot because it breaks XHR data request.

推荐答案

不手动处理缓存头是不可能的.通常,304 响应无法通过 XHR API 提供:

Without handling cache headers manually, it is not possible. Normally, 304 responses are not made available through the XHR API:

对于由用户代理生成的条件请求导致的 304 Not Modified 响应用户代理必须像服务器提供具有适当内容的 200 OK 响应一样.

For 304 Not Modified responses that are a result of a user agent generated conditional request the user agent must act as if the server gave a 200 OK response with the appropriate content.

jQuery 通常不知道有 304 响应,因为浏览器会礼貌地向 JavaScript 撒谎,告知网络上实际发生的事情.

jQuery normally doesn't know there was a 304 response, because the browser tells polite lies to JavaScript about what is actually happening over the network.

但有个好消息(有点):您可以让 Ajax 生成 304 响应,但只能通过手动设置 HTTP 缓存标头 请求中的 If-Modified-SinceIf-None-Match:

But there is good news (kind of): you can get Ajax to produce a 304 response, but only by manually setting the HTTP cache headers If-Modified-Since or If-None-Match in the request:

用户代理必须允许 setRequestHeader() 通过设置请求头来覆盖自动缓存验证(例如,If-None-MatchIf-Modified-由于),在这种情况下,必须通过 304 Not Modified 响应.

The user agent must allow setRequestHeader() to override automatic cache validation by setting request headers (e.g., If-None-Match, If-Modified-Since), in which case 304 Not Modified responses must be passed through.

因此,您可以使用以下代码:

So, you can use code like:

var xhr = new XMLHttpRequest();
xhr.open("GET", "foo.html");
xhr.setRequestHeader("If-Modified-Since", "Fri, 15 Feb 2013 13:43:19 GMT");
xhr.send();

一个基本困难是您如何知道要发送的最后修改日期或ETag?em> 浏览器有用于发送请求的缓存信息,但它不会与 JavaScript 共享该信息.幸运的是,jQuery 会跟踪来自 Ajax 响应的 Last-ModifiedETag 标头,因此您可以使用 ifModified:true 来让 jQuery 设置它们下次发送对该资源的请求时,标头值.

One fundamental difficulty is how do you know what last-modified date or ETag to send? The browser has cache information that it uses for sending requests, but it won't share that information with JavaScript. Fortunately, jQuery keeps track of the Last-Modified and ETag headers from Ajax responses, so you can use ifModified:true to have jQuery set those header values the next time it sends a request for that resource.

有两点需要注意:

  • 304 响应不携带数据.这是设计使然.假设是,如果您选择使用缓存,则应该在缓存中拥有一份数据副本!如果没有从服务器获取数据是一个问题(即,因为您还没有这些数据),为什么要使用缓存?当你手头有旧数据而只想要新数据时,应该使用缓存;因此,使用 304 不返回任何数据应该不是问题.

  • 304 responses do not carry data. This is by design. The assumption is that if you have elected to use caching, you should have a copy of the data already in your cache! If getting no data from the sever is a problem (i.e., because you don't already have that data) why are you using caching? Caching should be used when you have the old data on hand and only want new data; thus, getting back no data with a 304 should not be a problem.

jQuery 必须有一个上次修改的日期或一个 ETag(与 If-None-Match 一起使用)存储在前一个请求中.过程是这样的:

jQuery must have a last-modified date or an ETag (to use with If-None-Match) stored from a previous request. The process goes like this:

  • First fetch:jQuery 没有缓存信息,所以它不会发送 If-Modified-SinceIf-None-Match.当响应返回时,服务器可能会宣布最后修改的数据或 ETag,jQuery 存储这些数据以备将来使用.

  • First fetch: jQuery has no cache information, so it doesn't send If-Modified-Since or If-None-Match. When the response comes back, the server may announce a last-modified data or an ETag, which jQuery stores for future use.

后续提取:jQuery 缓存上次提取的信息并将该数据转发到服务器.如果资源没有改变,Ajax 请求会得到 304 响应.如果资源已更改,则 Ajax 请求会收到 200 响应,以及新的缓存信息供 jQuery 用于其下一次获取.

Subsequent fetches: jQuery has cache information from the last fetch and forwards that data to the server. If the resource has not changed, the Ajax request gets a 304 response. If the resource has changed, the Ajax request gets a 200 response, along with new cache information for jQuery to use for its next fetch.

jQuery 不会在页面重新加载之间保留缓存信息(例如,在 cookie 中).因此,页面重新加载后对资源的第一次获取永远不会是 304,因为 jQuery 没有要发送的缓存信息(即,我们重置回第一次获取"的情况).jQuery 没有理由不能持久化缓存信息,但目前它没有.

jQuery does not persist cache information (e.g., in cookies) between page reloads, however. Therefore, the first fetch of a resource after a page reload will never be a 304, because jQuery has no cache information to send (i.e., we reset back to the "first fetch" case). There is no reason why jQuery couldn't persist cache information, but at present it doesn't.

这里的底线是,您可以使用缓存标头来获取 JavaScript 304 响应,但您无法访问浏览器自己的 ETag 或特定资源的上次修改日期.因此,浏览器本身可能知道有关资源的缓存信息,但您的 JavaScript 代码不知道.在这种情况下,浏览器将使用其缓存标头来潜在地获得真正的 304 响应,但会将 200 响应转发给您的 JavaScript 代码,因为 JavaScript 没有发送任何缓存信息.

The bottom line here is that you can use cache headers to get a JavaScript 304 response, but you can't access the browser's own ETag or last-modified date for a particular resource. So, the browser itself might know caching information about a resource, but your JavaScript code does not. In that case, the browser will use its cache headers to potentially get a real 304 response, but forward a 200 response to your JavaScript code, because JavaScript didn't send any cache information.

使 JavaScript 304 请求与实际网络 304 响应完全一致是不可能的,因为浏览器已知的缓存信息和 JavaScript 代码已知的缓存信息可能会以不可预测的方式不同.但是,在大多数情况下正确获取 304 请求足以满足大多数实际开发需求.

It is not possible to make JavaScript 304 requests align perfectly with actual network 304 responses, because the cache information known by your browser and the cache information known by your JavaScript code may differ in unpredictable ways. However, getting 304 requests correctly most of the time is good enough for most practical development needs.

这是一个用 Node.js 编写的简短服务器示例(但它应该足够简单以移植到其他语言):

Here's a brief server example written in Node.js (but it should be simple enough to port to other langauges):

require("http").createServer(function (req, res) {
  console.log(req.headers["if-modified-since"]);

  // always send Last-Modifed header
  var lastModDate = "Fri, 13 Feb 2013 13:43:19 GMT";
  res.setHeader("Last-Modified", lastModDate);

  // if the request has a If-Modified-Since header,
  //   and it's newer than the last modification,
  //   then send a 304 response; otherwise send 200
  if(req.headers["if-modified-since"] &&
     Date.parse(lastModDate) <= Date.parse(req.headers["if-modified-since"])) {
    console.log("304 -- browser has it cached");
    res.writeHead(304, {'Content-Type': 'text/plain'});
    res.end();
  } else {
    console.log("200 -- browser needs it fresh");
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('some content');
  }

}).listen(8080);

运行此服务器时,您可以在浏览器中加载页面并在浏览器控制台中执行两种不同的测试:

When running this server, you can load the page in your browser and perform two different tests in your browser console:

var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.send();
xhr.onload = function() { console.log(xhr.status); }

这个脚本总是会看到一个 200 响应,即使浏览器提供了一个 If-Modified-Since 请求头并得到一个 304(这将发生在第一个之后的所有请求,在浏览器看到服务器的 Last-Modifed 响应标头之后).

This script will always see a 200 response, even if the browser supplies a If-Modified-Since request header and gets a 304 (which will happen all requests after the first, after the browser sees the server's Last-Modifed response header).

相比之下,这个脚本将总是看到 304 响应:

By contrast, this script will always see 304 response:

var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.setRequestHeader("If-Modified-Since", "Fri, 15 Feb 2013 13:43:19 GMT");
xhr.send();
xhr.onload = function() { console.log(xhr.status); }

脚本提供自己的If-Modified-Since 请求标头(服务器上次修改日期后两天);它不依赖于浏览器为 If-Modified-Since 提供的任何内容,因此允许(根据 XHR 规范)查看 304 响应.

The script supplies its own If-Modified-Since request header (two days after the server's last-modified date); it does not rely on whatever the browser supplies for If-Modified-Since, and therefore is allowed (per the XHR spec) to see 304 responses.

最后,这个脚本总是会看到一个200:

Finally, this script will always see a 200:

var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.setRequestHeader("If-Modified-Since", "Fri, 12 Feb 2013 13:43:19 GMT");
xhr.send();
xhr.onload = function() { console.log(xhr.status); }

这是因为脚本使用了在服务器上次修改日期之前的 If-Modified-Since,所以服务器总是发送 200.服务器不会发送 304 因为它假定客户端没有最新版本的缓存副本(即,客户端宣布自 2 月 12 日以来它已经看到了更改,但是有一个2 月 13 日的变化,客户显然没有看到).

This is because the script uses a If-Modified-Since that is prior to the server's last-modified date, so the server always sends a 200. The server won't send a 304 because it assumes the client doesn't have a cached copy of the most recent version (i.e., the client announces that it's seen changes since Feb 12, but there was a change on Feb 13 that the client apparently hasn't seen).

这篇关于如何检查 jQuery.ajax() 请求头状态是否为“304 Not Modified"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆