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

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

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

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

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

注意,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程序的时候不妨送佛送到西,在客户端再做一次缓存,进一步提高数据载入速度。那就是在载入数据的同时将数据缓存在浏览器内存中,一旦数据被载入,只要页面未刷新,该数据就永远的缓存在内存中,当用户再次查看该数据时,则不需要从服务器上去获取数据,极大的降低了服务器的负载和提高了用户的体验。

(0)

相关推荐

  • 浅谈Ajax请求与浏览器缓存

    在现代Web应用程序中,前端代码充斥着大量的Ajax请求,如果对于Ajax请求可以使用浏览器缓存,那么可以显著地减少网络请求,提高程序响应速度. 1. Ajax Request 使用jQuery框架可以很方便的进行Ajax请求,示例代码如下: $.ajax({ url : 'url', dataType : "xml", cache: true, success : function(xml, status){ } }); 非常简单,注意其中的第4行代码:cache:true,显式的要

  • Ajax中浏览器的缓存问题解决方法

    每次清除缓存后,就会得到一个新的数据,所以归根到底就是浏览器缓存问题.纠结了很久,终于解决了,在这里总结一下. 我们都知道ajax能提高页面载入的速度主要的原因是通过ajax减少了重复数据的载入,也就是说在载入数据的同时将数据缓存到内存中,一旦数据被加载其中,只要我们没有刷新页面,这些数据就会一直被缓存在内存中,当我们提交 的URL与历史的URL一致时,就不需要提交给服务器,也就是不需要从服务器上面去获取数据,虽然这样降低了服务器的负载提高了用户的体验,但是我们不能获取最新的数据.为了保证我们读

  • Js 代码中,ajax请求地址后加随机数防止浏览器缓存的原因

    看到别人写的JS,ajax请求地址后加随机参数,比如XXXX?t= + new Date().getTime(). 一开始搞不懂为什么,网上查了资料,原因是防止浏览器缓存. 浏览器为了提高用户访问同一页面的速度,会对页面数据进行缓存.当url请求地址不变时, 有时候会导致浏览器不发送请求,直接从缓存中读取之前的数据. 如果数据改变了,而没加随机数,读取的数据会跟之前一样. 加上随机数,就是欺骗浏览器url改变了,会每次都向服务器发送请求而不去读缓存

  • Ajax清除浏览器js、css、图片缓存的方法

    做东东时都是把图片在服务器的地址存放在数据库里面,然后到浏览器中显示,但是后来发现了两个问题. 第一:为了安全起见,js是无法读取本地的图片的,不然你写一个js,岂不是可以获取任何人电脑里面的文件了. 第二:图片存在的是在服务器的硬盘上面,而不是在客户的硬盘里面,所以也是取不到的 后来在网上找方法,找的方法,都是各种转换二进制到xml中,的各种高大上的答案,然后本人又实在太懒了,就自己想了一个 方法,就是利用BufferedImage这个类. 开始 首先说说我的思路,就是把本地的图片,加载到内存

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

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

  • 解析jquery中的ajax缓存问题

    jquery的ajax请求默认请求cache是true 也就是开启的,dataType为script和jsonp时默认为false.现在我要在浏览器里读取缓存,因为ajax请求的数据很大,请求一次就够了.但是问题来了,在FF里面,是没有ajax缓存的,也就是每次都会触发ajax请求,这点和IE不一样.所以在这里就得注意,做个判断,阻止触发ajax事件. 复制代码 代码如下: function ajax_show(apartId,roomClass,sortTile){          HX_T

  • 浅析IE浏览器关于ajax的缓存机制

    IE浏览器对于同一个URL只返回相同结果.因为,在默认情况下,IE会缓存ajax的请求结果.对于同一个URL地址,在缓存过期之前,只有第一次请求会真正发送到服务端.大多数情况下,我们使用ajax是希望实现局部刷新的,所以这就牵扯到一个改进的问题. 如果想每次都获取到最新数据,我们只需保证每次传入的URL不一样.最简单的方法就是通过给url拼接参数.利用math函数的random()方法生成随机数. 比如访问百度www.baidu.com,我们就可以把地址写成www.baidu.com?t=Mat

  • 基于HTTP浏览器缓存机制全面解析

    目录 什么是浏览器缓存 非HTTP协议定义的缓存机制 缓存流程图 HTTP缓存机制 服务端如何判断缓存已失效 Last-Modified/If-Modified-Since Etag/If-None-Match 为什么有了Last-Modified还要Etag? 200 OK(from cache)与304 Not Modified的区别 200 OK( from cache ) 出现操作: 304 Not Modified 出现操作: 缓存的不同来源 不能被缓存的请求 什么是浏览器缓存 Web

  • 浅谈Ajax的缓存机制

    Ajax的缓存机制和浏览器处理资源时的缓存机制是一样的. 三条简单规则: 只要是URL相同的GET请求,浏览器会使用缓存(当然还要看服务器的Cache-Control/Expires/Last-Modified/ETag头的设置). 只要是POST请求,浏览器都不会缓存. Https的请求,浏览器不会缓存(绝大数情况如此,但是也有例外,据说FF浏览器是例外). 补充: 在URL中拼入随机的查询字符串可以使浏览器认为这是一个新的请求,从而不使用缓存. 在Ajax的请求中设置Http头: If-Mo

  • Hibernate缓存机制实例代码解析

    本文研究的主要是Hibernate缓存机制的相关内容,具体如下. 演示项目: Student.java: public class Student { /*学生ID*/ private int id; /*学生姓名*/ private String name; /*学生和班级的关系*/ private Classes classes; //省略setter和getter方法 } Classes.java: public class Classes { /*班级ID*/ private int i

  • 详解浏览器的缓存机制

    目录 前言 1 浏览器缓存 1.1 浏览器缓存 1.2 浏览器缓存的意义 2 缓存类型 2.1 第一次请求数据 2.2 强制缓存 2.3 协商缓存 2.4 强制缓存和协商缓存的关系 3 缓存相关header 3.1 强制缓存 3.2 协商缓存 3.3 缓存请求 4 实例分析 4.1 官网首页: 4.2 社区 4.3 云市场 4.4 个人中心 4.5 论坛 4.6 App 总结 前言 浏览器缓存是前端性能优化的重要一环,对于前端效率提升的重要性,不言而喻. 之前对于浏览器缓存也是一知半解,这次借着

  • 详解vue服务端渲染浏览器端缓存(keep-alive)

    在使用服务器端渲染时,除了服务端的接口缓存.页面缓存.组建缓存等,浏览器端也避免不了要使用缓存,减少页面的重绘. 这时候我们就会想到vue的keep-alive,接下来我们说一下keep-alive的使用 假如现在我们有两个页面,home.vue 和 about.vue home.vue <template> <div> home </div> </template> <script> export default { name: Home, c

  • localStorage的黑科技-js和css缓存机制

    一.发现黑科技的起因 今天在微信公众号看到一篇技术博文,想用印象笔记收藏,所以发送了文章链接到pc上.然后习惯性地打开控制台,看看源码,想了解下最近微信用了什么新技术. 呵呵,以下勾起了我侦探的欲望.页面加载后的异常点就是只加载了一个js,如下图所示: 我很诧异,为什么已经开启了Disable cache,js只加载了一个,而且体积这么小.接着,我按住Ctrl+O进行资源文件查找,发现我被"忽悠"了.其实根本就不止一个js文件. 脑袋里灵光一闪,不会是用localStorage做了缓存

  • 概述如何实现一个简单的浏览器端js模块加载器

    在es6之前,js不像其他语言自带成熟的模块化功能,页面只能靠插入一个个script标签来引入自己的或第三方的脚本,并且容易带来命名冲突的问题.js社区做了很多努力,在当时的运行环境中,实现"模块"的效果. 通用的js模块化标准有CommonJS与AMD,前者运用于node环境,后者在浏览器环境中由Require.js等实现.此外还有国内的开源项目Sea.js,遵循CMD规范.(目前随着es6的普及已经停止维护,不论是AMD还是CMD,都将是一段历史了) 浏览器端js加载器 实现一个简

随机推荐