当前位置: 首页 > 面试题库 >

如何检查jQuery.ajax()请求标头状态是否为“ 304未修改”?

怀晋
2023-03-14
问题内容

如何检查jQuery.ajax()请求标头状态是否为“ 304未修改”?

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

ifModified:true 并没有太大帮助,因为它中断了XHR数据请求。


问题答案:

如果不手动处理高速缓存头,则不可能。通常,XHR API无法提供304个响应:

对于由于用户代理生成的条件请求 产生的304未修改响应, 用户代理必须像服务器给出200 OK响应并提供适当的内容一样起作用

jQuery通常不知道响应是304,因为浏览器会向JavaScript礼貌地告知网络实际发生的情况。

但是有一个好消息(有点):您 可以
使Ajax产生304响应,但只能通过手动设置HTTP缓存头
If-Modified-SinceIf-None-Match在请求中进行:

用户代理必须允许setRequestHeader()通过设置请求报头(例如,覆盖自动缓存验证If-None-MatchIf- Modified-Since),在这种情况下,304个未修改响应必须被通过。

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

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- ModifiedETag标头,因此您可以ifModified:true在下一次向该资源发送请求时让jQuery设置标头值。

需要注意的两件事:

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

  • jQuery必须具有If-None-Match前一个请求存储的上次修改日期或ETag(用于)。过程如下:

    • 首先获取:jQuery没有缓存信息,因此它不发送If-Modified-SinceIf-None-Match。当响应返回时,服务器可以宣布jQuery存储以供将来使用的最后修改的数据或ETag。

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

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

最重要的是,您可以使用缓存标头来获取JavaScript 304响应,但是您不能访问 浏览器自己的
ETag或特定资源的最后修改日期。因此,浏览器本身可能知道有关资源的缓存信息,但是您的JavaScript代码却不知道。在这种情况下,浏览器将使用其缓存标头潜在地获得真正的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即使浏览器提供了一个If-Modified-Since请求标头并得到一个304(在浏览器看到服务器的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请求标头(服务器的上次修改日期后两天)。它不依赖于浏览器提供的任何内容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。服务器不会发送“
a”,304因为它假定客户端没有最新版本的缓存副本(即,客户端宣布自2月12日以来已看到更改,但是2月13日发生了更改,客户端显然尚未看到)。



 类似资料:
  • 问题内容: 我想检查服务器端是否对我的php页面的请求是ajax请求。 我看到了两种方法可以做到这一点: 第一种方法:在请求中发送一个参数,该参数告诉页面这是AJAX请求(= ) mypage.php: 第二种方式:将标头设置为: 客户端js: mypage.php: 事实是,这两种方法很容易被黑,因此检查我是否收到这样的AJAX请求并不安全。 如何检查我是否收到AJAX请求? 问题答案: 没有确

  • 有没有一种方法来检测响应与Alamofire 4?我发现Alamofire总是200,即使服务器响应304。 网络呼叫设置: Alamofire响应报头 服务器响应

  • 问题内容: 我正在写一个可以设置标题的库。如果标题已经发送,我想给出一个自定义错误消息,而不是让它失败并显示Node.js给出的“发送后无法设置标题”消息。那么如何检查标头是否已经发送? 问题答案: 编辑:从Express 4.x开始,您需要使用res.headersSent。 还要注意,您可能要在检查之前使用setTimeout,因为在调用res.send()之后,它不会立即设置为true。资源

  • 问题内容: 似乎只有在ajax请求能够从服务器获得某些响应时,才会触发成功,错误和完整的回调。 因此,如果我关闭服务器,则不会执行以下错误回调,并且请求将以静默方式失败。 当根本无法访问服务器时,抛出错误的最佳方法是什么。 编辑-从我尝试过的内容来看,似乎jQuery的内置错误处理不适用于JSONP或dataType:“ script”。因此,我将尝试设置手动超时。 编辑-做了一些进一步的研究,看

  • 问题内容: 有没有一种方法可以检查Python中的请求是否为AJAX? 相当于PHP的? 问题答案: 如果AJAX框架在其请求中设置了X-Requested-With标头,则您将能够使用该标头来检测AJAX调用。这取决于客户端框架。 掌握HTTP标头取决于您选择的Python框架。在Django中,对象具有可以直接使用的方法。

  • 问题内容: 如何检索请求的响应标头?以下是我提出的要求。 提前致谢! 问题答案: 如果响应为类型,则可以从获取标头。 因此,当您使用Alamofire responseJSON时,可以像这样访问NSHTTPURLResponse属性: 正如苹果文件所说: 包含所有HTTP标头字段的字典,该字段作为服务器响应的一部分收到。通过检查此词典,客户端可以看到HTTP服务器返回的“原始”标头信息。 该词典中