jquery.ajax中的ifModified参数的误解
原来以为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/
3、https://bugzilla.mozilla.org/show_bug.cgi?id=428916
jquery.ajax中的ifModified参数的误解的更多相关文章
- jquery ajax 中各个事件执行顺序
jquery ajax 中各个事件执行顺序如下: 1.ajaxStart(全局事件) 2.beforeSend 3.ajaxSend(全局事件) 4.success 5.ajaxSuccess(全局事 ...
- jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?
1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...
- 【转】Ajax中send方法参数的使用(get/post)
Ajax中send方法参数的使用 一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null. 例如 : ...
- jquery ajax/post/get 传参数给 mvc的action
jquery ajax/post/get 传参数给 mvc的action1.ActionResult Test1 2.View Test1.aspx3.ajax page4.MetaObjec ...
- [转载]jquery ajax/post/get 传参数给 mvc的action
jquery ajax/post/get 传参数给 mvc的action 1.ActionResult Test1 2.View Test1.aspx 3.ajax page 4.MetaO ...
- jquery ajax中success与complete的执行顺序
jquery ajax中success与complete的执行顺序 jquery中各个事件执行顺序如下: 1.ajaxStart(全局事件) 2.beforeSend 3.ajaxSend(全局事件) ...
- jquery ajax中 php前台后台文件中编辑都是uft-8,返回数据还是乱码
jquery ajax中 前台后台文件中编辑都是uft-8,返回数据还是乱码 解决如下: 在后台处理文件里面需要再加编辑 header("Content-Type:text/html;cha ...
- jQuery ajax中的参数含义
所有options均可选,下面简要说明每个option 1.async 默认为true,即请求为异步请求,这也是ajax存在的意义.但同时也可以将这个参数设置为false,实现同步请求.(同步请求会锁 ...
- jQuery ajax中serialize()方法增加其他参数
表单提交 使用jQuery.ajax()进行表单提交时,需要传递参数,最直接的方法便是使用Form的serializa()将表单序列化,前提只是将Form表单中的name属性与数据库的字段名保持一致便 ...
随机推荐
- pt-online-schema-change原理解析 博客相关需要阅读
xiaoboluo768 http://www.lai18.com/user/481193.html 都说pt-toolkit工具集中的pt-online-schema-change可以在线不锁 ...
- 日志文件 的管理 logrotate 配置
于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以使用logrotate 程序用来管理系统中的最新的事件, 对于Linux 的系统安全来说,日志文件是极其重要的工具.系统管理员可以 ...
- PhpCMS标签:专题模块special标签
专题模块 专题模块PC标签调用说明 模块名:special 模块提供的可用操作 操作名 说明 lists 专题列表 content_list 专题信息列表 hits 专题信息点击排序 下面对所有的操作 ...
- c++暂停
#include<cstdlib> 加入这个 然后 system("pause");
- Asp.Net 之 使用Form认证实现用户登录 (LoginView的使用)
1. 创建一个WebSite,新建一个页面命名为SignIn.aspx,然后在页面中添加如下的代码 <div class="div_logView"> <asp: ...
- Java作业代写
作业一 试用java编写一个九九乘法表并打印. 作业二: 设计两个人类与书类,并设置两者的关系,试用人去找书,书去找人,假如某人有一个儿子,它也有一本书,试用儿子去找书,书找儿子. 大作业 熟悉QQ农 ...
- Android 自学之列表视图ListView和ListActivity
ListView是手机系统中使用非常广泛的一种组件,它以垂直列表的形式显示所有列表项. 创建ListView有两种方式: 直接使用ListView创建. 让Activity继承ListActivity ...
- 自定义android Dialog
1.自定义Dialog: import android.app.AlertDialog; import android.app.Dialog; import android.content.Conte ...
- html css中id和class的区别比较
在定义样式的时候,有时候会将id和class的用法弄混淆,所以在这里特意说明一下: id和class属性是网页中两个通用的属性,它们协同工作使整个页面变得丰富多彩.当我们为一个元素定义样式时.可以使用 ...
- PetShop
Microsoft .NET Pet Shop 4:将 ASP.NET 1.1 应用程序迁移到 2.0 发布日期: 2006-5-9 | 更新日期: 2006-5-9 适用于:Microsoft .N ...