原来以为ifModified是为了在AJAX请求是发送 If-Modified-Since头,让服务端返回304。

测试代码如下:

$(function () {
test();
window.setTimeout(test, 5000);
}); function test() {
$.ajax({
type: "GET",
url: url,
ifModified: true,
success: function (d, textStatus, xhr) {
console.log(xhr.status);
console.log(d == undefined);
}
});
}

chrome:

network 为 304,304

console为  200 false, 304 true

ie10

network为 304, 304

console为 200 false, 304 true

firefox:

network为 304, 200(from cache)

console为 200 false, 200 false

上述测试是建立在已经访问过的基础上进行的,因此第一个请求都为304。

测试结果有几个疑问

1、为什么network监控的响应码与jqXHR.status有不一致的情况

2、chrome与ie10为什么第一次请求可以获取到内容,但同样的304返回,第二次却内容为undefined

3、firefox的第二次请求为什么直接从cache取数据

据文档 XHR API

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. 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.

就是说一般情况下,如果服务器返回304后,浏览器会进行转换。此时jqXHR.status应该是200,并且浏览器会自动将缓存的内容发送给jqXHR(304,服务器是不会发送内容信息的);

但可以通过jqXHR.setRequestHeader(If-Modified-Since)来重载该行为,如果服务端会返回304,则把该结果直接传递给 jqXHR。

据此我们回答了第一个疑问。

那么第二个问题是怎么回事?

查看了network中的请求,二次请求都有带 If-Modified-Since 的头,没什么发现

在jq的源码发现了以下代码

// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) { if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
jQuery.lastModified[ ifModifiedKey ] = lastModified;
}
if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
jQuery.etag[ ifModifiedKey ] = etag;
}
}

这是从响应获取Last-Modified头的过程

// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
if ( s.ifModified ) {
ifModifiedKey = ifModifiedKey || s.url;
if ( jQuery.lastModified[ ifModifiedKey ] ) {
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
}
if ( jQuery.etag[ ifModifiedKey ] ) {
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
}
}

这是设置If-Modified-Since头的过程

回到主题 ifModified 参数,文档如下

Allow the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header. In jQuery 1.4 this technique also checks the 'etag' specified by the server to catch unmodified data.

文档说得不是很清楚,看代码的实现。

jq根据jQuery.lastModified字典中是否包含数据来决定是否设置If-Modified-Since。那第一次请求jQuery.lastModified是没有数据的(JS是无法获取浏览器缓存的信息),因此第一次请求jqXHR是没有设置If-Modified-Since,那也就解释了第一次请求jqXHR.status为200。因为有了第一次请求,jq获取获取到第一次请求响应中的Last-ModifiedjQuery.lastModified有了数据,第二次请求jqXHR是会加上If-Modified-Since头的,因此jqXHR.status收到了浏览器直接传递过来的请求响应及内容。

搞定了第二个疑问。

第三个问题看了一些文档还没有明确的结论,估计是firefox在xhr在处理cache上有些不同,服务器响应头有包含

Cache-Control:public, max-age=18000

总结下:

jquery ifModified参数主要是为了在通过JS检测资源是否发生变化(304),并且在页面的第一个AJAX请求jqXHR.status永远不会返回304。

参考文档

1、http://www.w3.org/TR/2009/WD-XMLHttpRequest-20091119/

2、http://stackoverflow.com/questions/5173656/how-to-check-if-jquery-ajax-request-header-status-is-304-not-modified

3、https://bugzilla.mozilla.org/show_bug.cgi?id=428916

jquery.ajax中的ifModified参数的误解的更多相关文章

  1. jquery ajax 中各个事件执行顺序

    jquery ajax 中各个事件执行顺序如下: 1.ajaxStart(全局事件) 2.beforeSend 3.ajaxSend(全局事件) 4.success 5.ajaxSuccess(全局事 ...

  2. jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?

    1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...

  3. 【转】Ajax中send方法参数的使用(get/post)

    Ajax中send方法参数的使用 一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null. 例如 : ...

  4. jquery ajax/post/get 传参数给 mvc的action

    jquery ajax/post/get 传参数给 mvc的action1.ActionResult Test1    2.View  Test1.aspx3.ajax page4.MetaObjec ...

  5. [转载]jquery ajax/post/get 传参数给 mvc的action

    jquery ajax/post/get 传参数给 mvc的action 1.ActionResult Test1     2.View  Test1.aspx 3.ajax page 4.MetaO ...

  6. jquery ajax中success与complete的执行顺序

    jquery ajax中success与complete的执行顺序 jquery中各个事件执行顺序如下: 1.ajaxStart(全局事件) 2.beforeSend 3.ajaxSend(全局事件) ...

  7. jquery ajax中 php前台后台文件中编辑都是uft-8,返回数据还是乱码

    jquery ajax中 前台后台文件中编辑都是uft-8,返回数据还是乱码 解决如下: 在后台处理文件里面需要再加编辑 header("Content-Type:text/html;cha ...

  8. jQuery ajax中的参数含义

    所有options均可选,下面简要说明每个option 1.async 默认为true,即请求为异步请求,这也是ajax存在的意义.但同时也可以将这个参数设置为false,实现同步请求.(同步请求会锁 ...

  9. jQuery ajax中serialize()方法增加其他参数

    表单提交 使用jQuery.ajax()进行表单提交时,需要传递参数,最直接的方法便是使用Form的serializa()将表单序列化,前提只是将Form表单中的name属性与数据库的字段名保持一致便 ...

随机推荐

  1. vim中光标的前进和后退

    流行的文本编辑器通常都有前进和后退功能,可以在文件中曾经浏览过的位置之间来回移动.在 vim 中使用 Ctrl-O 执行后退,使用 Ctrl-I 执行前进.相关帮助: :help CTRL-O  :h ...

  2. 小白日记26:kali渗透测试之提权(六)--收集敏感信息,隐藏痕迹

    提权后操作 提权之后,要收集目标系统的重要信息LINUX /etc/resolv.conf       #查看DNS配置,是否可以进行DNS篡改或劫持 /etc/passwd         #存放账 ...

  3. Cable master

    Description Inhabitants of the Wonderland have decided to hold a regional programming contest. The J ...

  4. 有关ftp4j的FTPListParseException异常

    昨天换了个ftp服务器,发现程序出现了异常it.sauronsoftware.ftp4j.FTPListParseException,网上搜了下,说是FTPClient.list()时it.sauro ...

  5. LeetCode 231

    Power of Two Given an integer, write a function to determine if it is a power of two. /************* ...

  6. [改善Java代码]用偶判断,不用奇判断

    建议21: 用偶判断,不用奇判断 public class Client { public static void main(String[] args) { Scanner in = new Sca ...

  7. 关于使用vss版本管理工具中的sln,suo文件作用

    Visual Studio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件.为解决方案资源管理器提供显示管理文件的图形接口所需的信息 从而在每次继续开发 ...

  8. 【数论,找规律】Uva 11526 - H(n)

    原来做过的题再看还是没想出来,看来当时必然没有真正理解.这次回顾感觉理解更透彻了. 网上的题解差不多都是一个版本,而且感觉有点扯.根据n=20猜出来的? 好吧哪能根据一个就猜到那么变态的公式.其实这题 ...

  9. Netty线程模型

    一.Reactor模型 1.单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接: 2)作为NI ...

  10. Oracle导入SQL脚本执行 scott 用户下的表删除了

    执行 .sql 文件时,应在 sqlplus  或 cmd 中执行,速度比plsql 中的command window 中书许多, scott 用户下的表删除了 可以执行如下 @D:\app\Admi ...