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

 更新时间:2016年06月21日 18:05:42   作者:code_bunny  
这里我们来解析浏览器端的AJAX缓存机制,来共同看一下AJAX缓存与HTTP缓存的关系以及AJAX缓存的刷新时间问题

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里,你可以看到我们在响应头信息里设置了以上三个响应头

2016621174746971.png (565×227)

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

2016621174823835.png (592×155)

最后一次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请求的效果:

2016621175010316.png (595×282)

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

2016621175032362.png (600×147)

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

2016621175400871.png (583×130)

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

2016621175426365.png (587×258)

注意,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中valueOf函数与toString方法深入理解

    JavaScript中valueOf函数与toString方法深入理解

    基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外。它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下
    2012-12-12
  • Bootstrap的popover(弹出框)2秒后定时消失的实现代码

    Bootstrap的popover(弹出框)2秒后定时消失的实现代码

    Bootstrap Popover(弹出框)是使用定制的 Jquery 插件创建的。它可以用来显示任何元素的一些信息。这篇文章主要介绍了Bootstrap的popover(弹出框)2秒后定时消失功能,需要的朋友参考下
    2017-02-02
  • JS 设计模式之:工厂模式定义与实现方法浅析

    JS 设计模式之:工厂模式定义与实现方法浅析

    这篇文章主要介绍了JS 设计模式之:工厂模式,结合实例形式分析了JS 工厂模式基本概念、原理、定义、实现方法与操作注意事项,需要的朋友可以参考下
    2020-05-05
  • js动画效果打开层 关闭层

    js动画效果打开层 关闭层

    js模拟弹窗效果代码,用层实现提示效果代码
    2008-04-04
  • JS前端使用Blob和File读取文件的操作代码

    JS前端使用Blob和File读取文件的操作代码

    JavaScript 无法处理二进制数据。如果一定要处理的话,只能使用 charCodeAt() 方法,一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成 Base64 编码,再进行处理,这篇文章主要介绍了JS前端使用Blob和File读取文件,需要的朋友可以参考下
    2022-11-11
  • 一篇文章教你JS函数继承

    一篇文章教你JS函数继承

    这篇文章主要介绍了js继承方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-09-09
  • JS模拟酷狗音乐播放器收缩折叠关闭效果代码

    JS模拟酷狗音乐播放器收缩折叠关闭效果代码

    这篇文章主要介绍了JS模拟酷狗音乐播放器收缩折叠关闭效果代码,涉及JavaScript响应鼠标事件控制页面元素样式变换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • JavaScript原始值与包装对象的详细介绍

    JavaScript原始值与包装对象的详细介绍

    这篇文章主要给大家介绍了关于JavaScript原始值与包装对象的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Knockoutjs 学习系列(一)ko初体验

    Knockoutjs 学习系列(一)ko初体验

    本篇主要简单介绍了knockoutjs中最重要的概念:可观察对象(数组)。非常不错具有参考借鉴价值,感兴趣的朋友快来围观吧
    2016-06-06
  • JavaScript通过filereader接口读取文件

    JavaScript通过filereader接口读取文件

    这篇文章主要为大家详细介绍了通过filereader接口读取文件,使用readAsDataURL方法预览图片的相关方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05

最新评论