解析浏览器端的AJAX缓存机制


Posted in Javascript onJune 21, 2016

AJAX的缓存是由浏览器维持的,对于发向服务器的某个url,ajax仅在第一次请求时与服务器交互信息,之后的请求中,ajax不再向服务器提交请求,而是直接从缓存中提取数据。
有些情况下,我们需要每一次都从服务器得到更新后数据。思路是让每次请求的url都不同,而又不影响正常应用:在url之后加入随机内容。
e.g.

url=url+"&"+Math.random();

Key points:
1.每次请求的url都不一样(ajax的缓存便不起作用)
2.不影响正常应用(最基本的)

这里我们由两条结论:

1:Ajax的缓存和HTTP的缓存是一样的
现代浏览器的HTTP和缓存机制比Ajax的XMLHttpRequest对象要差很多,所以它不认识也不关心Ajax请求.它仅仅是遵循普通的HTTP缓存规则,通过服务器返回的响应头来进行缓存.
如果你已经对 HTTP缓存 有了解,那么你可以把HTTP缓存的知识用对Ajax缓存的理解上. 他们只有一点不同的,就是设置响应头的方式会和普通文件不一样.
下面这些响应头可以让你的Ajax可缓存:
Expires: 这一项应该被设置成未来的某个合适的时间点,时间点的设置取决于内容变动的频繁程度.举个栗子,如果请求的是个库存数量,那么Expires的值可以是10秒以后.如果请求的是一个相片,那么Expires的值就可以久一点,因为它不会经常变动.Expires头可以让浏览器在一段时间内重用本地缓存数据,从而避免任何不必要的与服务器数据交互.
Last-Modified: 设置这一项是一个很好的选择,通过它,浏览器在发送条件性GET请求的时候会使用请求头里的 If-Modified-Since 来检查本地缓存的内容.如果数据不需要更新,服务器会返回304响应状态.
Cache-Control: 在合适的情况下,这个值应该被设置为 Public ,这样所有的中间代理和缓存都可以被保存并且与其他用户共享内容.在火狐里,它还支持HTTPS请求的缓存
当然,如果你使用POST方式发送Ajax是不能缓存的,因为POST请求永远不会被缓存.如果你的Ajax请求会产生其他作用(比如银行账户之间的转账),请使用POST请求.
我们设置了一个demo(这个demo已经不能看了?(?□?)ノ)来阐明这些头信息是如何工作的. 在HttpWatch里,你可以看到我们在响应头信息里设置了以上三个响应头

解析浏览器端的AJAX缓存机制

如果你规律的点击 ‘Ajax Update' 按钮,时间的改变会趋向于每隔一分钟一次.因为Expires响应头被设置为未来的一分钟.在下面这张截图里你可以看到:重复的点击更新按钮时,Ajax请求会读取浏览器本地的缓存而不会产生网络活动(发送和传输栏的值都是0)

解析浏览器端的AJAX缓存机制

最后一次1:06.531时刻的点击发送的Ajax请求产生了网络数据传输,因为缓存的数据已经超过了一分钟. 服务器返回200响应状态表示获取到了一份新的数据.
猜测这个demo应该是一个按钮,每点击一次获取一次当前时间然后回现在页面上.

2:IE浏览器在Expires时间过期之前不会刷新通过Ajax获取的内容.
有些时候,Ajax在页面加载的时候就被用来填充页面的某些部分(比如一个价格列表).它并不是通过用户的某个事件(比如点击某个按钮)触发的,而是在页面加载的时候就通过javascript来发送的.就好像Ajax请求和那些嵌入资源(比如js和css)是一样的.
如果你开发这样的页面,在刷新它的时候,很可能想要更新嵌入的Ajax请求内容.对于嵌入资源(CSS文件,图片等),浏览器会通过用户刷新的方式是F5(刷新)还是Ctrl+F5(强制刷新)来自动发送下列不同类型的请求:
1.F5(刷新): 如果请求内容带有 Last-Modified 响应头,那么浏览器会发送条件性更新请求. 它使用 If-Modified-Since 请求头进行比较,这样服务器就可以返回304状态来避免传输不必要的数据.
2.Ctrl+F5(强制刷新): 告诉浏览器发送无条件更新请求,请求头的 Cache-Control 被设置为‘no-cache'.这告诉所有的中间代理和缓存:浏览器需要获取最新的版本,无论它是否已经被缓存.
Firefox把这个刷新的方式传播到了那些在页面加载的时候就发送的Ajax请求上,把这些Ajax请求当成嵌入资源来处理.下面是HttpWatch在火狐下的截图,显示了Ajax Caching demo(这个demo已经不能看了?(?□?)ノ)刷新(F5)页面时Ajax请求的效果:

解析浏览器端的AJAX缓存机制

火狐确保Ajax发起的请求是条件性的.在这个例子里,如果缓存数据不到10秒,服务器返回304,超过10秒,服务器返回200,重新传送数据.
在ie里,加载页面时就发起的Ajax请求被看做是和页面其他部分刷新毫无关系的,也不会被用户的刷新方式所左右.如果缓存的ajax数据没有过期,就不会有GET请求发送到服务器.它会直接从缓存里读取数据,从HttpWatch里看就是(Cache)结果.下面这个图是在ie下缓存没有过期的情况下按F5刷新:

解析浏览器端的AJAX缓存机制

就算是通过 Ctrl+F5 强制刷新,通过Ajax获取的数据也是从缓存里读取:

解析浏览器端的AJAX缓存机制

这就意味着,任何通过Ajax得到的内容如果没有过期,在ie下都不会被更新 - 即使你使用Ctrl+F5强制刷新. 唯一能确保你获取最新数据的方法就是手动清楚缓存. 可以使用HttpWatch的工具栏:

解析浏览器端的AJAX缓存机制

注意,Cache结果和304结果是不同的.Cache其实是200(cache),304就是304.Cache其实没有向服务器发送请求,可以从chrome里看到,它的耗时是0,response也是空.而304不同,
304请求是浏览器发起了一个条件性的请求,这个请求携带了 If-Modified-Since 请求头,如果这个文件在浏览器发送的这个时间之后没有修改过,服务器端就回返回一个304状态,告诉浏览器使用它本地的缓存内容.它没有Cache快,因为请求还是发送到了服务器端,只不过服务器端没有发送数据.
可以看下taobao首页,里面既有200(cache)也有304.可以查看他们的区别.

总结:

我们都知道,ajax能提高页面载入的速度的主要原因是通过ajax减少了重复数据的载入,真正做到按需获取,既然如此,我们在写ajax程序的时候不妨送佛送到西,在客户端再做一次缓存,进一步提高数据载入速度。那就是在载入数据的同时将数据缓存在浏览器内存中,一旦数据被载入,只要页面未刷新,该数据就永远的缓存在内存中,当用户再次查看该数据时,则不需要从服务器上去获取数据,极大的降低了服务器的负载和提高了用户的体验。

Javascript 相关文章推荐
escape、encodeURI、encodeURIComponent等方法的区别比较
Dec 27 Javascript
又一个图片自动缩小的JS代码
Mar 10 Javascript
filemanage功能中用到的lib.js
Apr 08 Javascript
js onkeypress与onkeydown 事件区别详细说明
Dec 13 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
Mar 16 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
Aug 13 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
May 05 Javascript
JS实现随机颜色的3种方法与颜色格式的转化
Jan 05 Javascript
jQuery实现键盘回车搜索功能
Jul 25 jQuery
JavaScript中Object基础内部方法图
Feb 05 Javascript
Vue源码解析之数组变异的实现
Dec 04 Javascript
vue自定义指令实现方法详解
Feb 11 Javascript
JS实现对中文字符串进行utf-8的Base64编码的方法(使其与Java编码相同)
Jun 21 #Javascript
第十篇BootStrap轮播插件使用详解
Jun 21 #Javascript
JavaScript简单获取页面图片原始尺寸的方法
Jun 21 #Javascript
第九篇Bootstrap导航菜单创建步骤详解
Jun 21 #Javascript
js简单判断flash是否加载完成的方法
Jun 21 #Javascript
第八篇Bootstrap下拉菜单实例代码
Jun 21 #Javascript
JS实现获取剪贴板内容的方法
Jun 21 #Javascript
You might like
怎样才能成为PHP高手?学会“懒惰”的编程
2006/12/05 PHP
php 用checkbox一次性删除多条记录的方法
2010/02/23 PHP
PHP JSON 数据解析代码
2010/05/26 PHP
PHP开发负载均衡指南
2010/07/17 PHP
php foreach正序倒序输出示例代码
2014/07/01 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
textContent在Firefox下与innerText等效的属性
2007/05/12 Javascript
return false;和e.preventDefault();的区别
2010/07/11 Javascript
JavaScript Title、alt提示(Tips)实现源码解读
2010/12/12 Javascript
基于Bootstrap里面的Button dropdown打造自定义select
2016/05/30 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
jQuery调用Webservice传递json数组的方法
2016/08/06 Javascript
JavaScript无阻塞加载和defer、async详解
2017/02/26 Javascript
JS解决移动web开发手机输入框弹出的问题
2017/03/31 Javascript
jquery 一键复制到剪切板的实例
2017/09/20 jQuery
vue使用自定义icon图标的方法
2018/05/14 Javascript
JavaScript 中的 this 工作原理
2018/06/20 Javascript
浅谈在react中如何实现扫码枪输入
2018/07/04 Javascript
JS前端广告拦截实现原理解析
2020/02/17 Javascript
使用Node.js实现base64和png文件相互转换的方法
2020/03/11 Javascript
在Python3中使用asyncio库进行快速数据抓取的教程
2015/04/02 Python
python验证码识别教程之利用滴水算法分割图片
2018/06/05 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
详细分析Python collections工具库
2020/07/16 Python
安装python依赖包psycopg2来调用postgresql的操作
2021/01/01 Python
Python中对象的比较操作==和is区别详析
2021/02/12 Python
介绍一下Ruby中的对象,属性和方法
2012/07/11 面试题
春节联欢晚会主持词
2014/03/24 职场文书
乡村文明行动实施方案
2014/03/29 职场文书
门面房租房协议书
2014/12/01 职场文书
幼儿园小班教师个人工作总结
2015/02/06 职场文书
上课迟到检讨书范文
2015/05/06 职场文书
可怜妈妈观后感
2015/06/09 职场文书
企业培训简报范文
2015/07/20 职场文书
Oracle中update和select 关联操作
2022/01/18 Oracle