如何检查jQuery.ajax()请求 header 状态是否为“304未修改”?
即使请求的 header 为“304 Not Modified”,jqXHR.status
通常也返回200
。ifModified:true
does not help很多,因为它中断了XHR数据请求。
最佳答案
如果不手动处理高速缓存头,则不可能。通常,XHR API不会提供304个响应:
jQuery通常不知道响应是304,因为浏览器会向JavaScript礼貌地告知网络实际发生的情况。
但是有个好消息(您可以):您可以让Ajax产生304响应,但只能通过在请求中手动设置HTTP cache headers If-Modified-Since
或If-None-Match
来:
因此,您可以使用如下代码:
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?该浏览器具有用于发送请求的缓存信息,但不会与JavaScript共享该信息。幸运的是,jQuery跟踪Ajax响应中的
Last-Modified
和ETag
header ,因此您可以使用ifModified:true
让jQuery在下一次发送对该资源的请求时设置这些 header 值。需要注意的两件事:
If-None-Match
一起使用)。过程如下:If-Modified-Since
或If-None-Match
。当响应返回时,服务器可以宣布jQuery存储以供将来使用的最后修改的数据或ETag。 最重要的是,您可以使用缓存 header 来获取JavaScript 304响应,但是您不能访问浏览器自己的ETag或特定资源的最后修改日期。因此,浏览器本身可能知道有关资源的缓存信息,但是您的JavaScript代码却不知道。在这种情况下,浏览器将使用其缓存 header 潜在地获得真实的304响应,但是将200响应转发给您的JavaScript代码,因为JavaScript没有发送任何缓存信息。
不可能使JavaScript 304请求与实际的网络304响应完全匹配,因为浏览器已知的缓存信息和JavaScript代码已知的缓存信息可能会以不可预测的方式不同。但是,大多数时候正确地获取304个请求足以满足大多数实际的开发需求。
例
这是一个用Node.js编写的简短服务器示例(但它应该足够简单以移植到其他语言):
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);
运行此服务器时,可以在浏览器中加载页面并在浏览器控制台中执行两个不同的测试:
var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.send();
xhr.onload = function() { console.log(xhr.status); }
即使浏览器提供了
200
请求 header 并获得了If-Modified-Since
(在浏览器看到服务器的304
响应 header 之后,所有请求都将在第一个请求之后发生),该脚本仍将始终显示Last-Modifed
响应。相比之下,此脚本将始终看到304响应:
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
请求 header (服务器上次修改日期后两天);它不依赖于浏览器为If-Modified-Since
提供的内容,因此(根据XHR规范)被允许查看304个响应。最后,此脚本将始终显示
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日存在更改,客户端显然还没有看到)。关于ajax - 如何检查jQuery.ajax()请求 header 状态是否为 “304 Not Modified”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5173656/