web开发中的缓存问题的研究

  一般情况下,浏览器都会缓存已经访问过的页面内容,关于如何禁止浏览器缓存的介绍,在网上到处都有相关的文章,但是,关于浏览器如何利用缓存,如何处理缓存的讲解,却鲜有人谈及。我一直为这个问题所困惑,这个问题也是绝大多数有经验的 WEB 开发人员所共同面临的问题,我有些朋友已做过几十个大大小小的 WEB 项目,当与他们交流这些问题时,他们虽然也在项目中遇到和解决过这些问题,但由于没有足够的时间和精力来仔细思考这些问题的原因和细节,他们对这些问题始终也是一知半解、含糊不清,而目前又很少关于这些问题的专门和详细讲解,我最近用了两天的时间,把浏览器缓存的问题透彻地研究了一翻,主要包括一下方面的细节。

1
如何禁止浏览器缓存,这是最简单的问题,本来羞于在此讲解,但是为了完整性,不妨将其列为一个知识点。

2
浏览器在访问已缓存过的资源时,它在什么情况下会向服务器发送请求?在什么情况下根本就不向服务器发送请求。这与浏览器的缓存设置有关 ! 但是,由于几乎所有人的浏览器都是采用的默认设置,所以,重点应该放在分析浏览器的默认缓存设置的研究上。

3
当通过其他网页文档中的超链接来访问某一个已经缓存过的资源时,浏览器是否要向服务器发出访问请求?如果不发,则会出现一个问题 : 当销售一件商品后再回到商品库存的显示页面时,看到的还将是先前看到的内容,而不是更新的库存数据。但是,在访问一个普通的 HTML 文件时,如果浏览器每次都向服务器发送访问请求,效率就会相对低下,这就失去了缓存的意义和价值。所以,结论应是浏览器访问动态页面时不能使用缓存,而访问静态页面时应该使用缓存,但是,仅仅根据被访问页面的资源名称,浏览器是无法知道商品库存的显示页面是属于动态内容,还是属于静态内容。浏览器是根据什么方式来判断它缓存的资源是动态的,还是静态的呢?在什么请求下,它会对缓存的资源总是发出新的请求呢?

4
。对于缓存的内容,即使浏览器向服务器发送了请求,但服务器在接收到请求后,可能不会返回内容,而是让浏览器继续使用缓存的内容,这在实际应用中有什么好处呢?如何处理其具体细节呢?

5
。服务器端也有缓存,当服务器接收到浏览器的请求后,假设它返回响应内容,但返回的响应内容可能不是最新的内容,而很可能是一个旧的缓存版本,这又是怎么回事呢?
浏览器缓存内幕与 getLastModified 方法
HttpServlet 类中定义了一个 getLastModified 方法,其完整语法定义如下:
protected long getLastModified(HttpServletRequest req)
其中的返回值表示自 1970 1 1 日的 0 0 0 秒开始计算的一个毫秒数, HttpServlet 类中定义的 getLastModified 方法总是返回一个负数,在 HttpServlet 子类中可以对这个方法进行覆盖,以便返回一个代表当前输出的响应内容的修改时间, HttpServlet 类的 service 方法可以根据这个返回值在响应消息中自动生成 Last-Modified 头字段。

一般情况下,浏览器都会缓存已经访问过的页面内容, getLastModified 方法的返回值可以影响浏览器如何处理和利用缓存内容。在详细了解 getLastModified 方法的应用之前,应该先对浏览器的缓存机制有所了解。

单击 IE 浏览器的 工具 “Internet 选项 菜单,打开 “Internet 选项 对话框,接着再单击 常规 选项卡中的 “Internet 临时文件 栏中的 设置 按钮,打开 设置 对话框。 设置 对话框的 “Internet 临时文件夹 栏中,可以看到浏览器保存所有缓存页面内容的文件夹的完整目录名称。

 “
每次访问此页时检查 选项表示浏览器每次访问一个页面时,不管浏览器是否缓存过此页面,都要向服务器发出访问请求。这种设置的优点是实时性很强,肯定能够访问到网页的最新内容,但是如果网页内容很少更新,这种设置的访问效率就比较低了。

每次启动 Internet Explorer 时检查 选项表示在浏览器的每次启动运行期间,在第一次访问一个页面时,不管浏览器是否缓存过此页面,都要向服务器发出访问请求,但是在浏览器的本次启动运行期间对该页面的后续访问,浏览器将不再向服务器发出访问请求,而是直接使用缓存中的内容。这种设置具有较高的访问效率,同时也兼顾了较好的实时性,它可以保证每次启动浏览器后看到的都是最新的网页内容。  

自动 选项与 每次启动 Internet Explorer 时检查 选项的功能相似,只是对图像的访问有所不同,如果随着时间的推移,浏览器发现网页上的图像更新并不频繁,这样,即使浏览器在对某个已缓存的图像执行本次启动运行以来的第一次访问时,它也不一定会向服务器发出访问请求,而是干脆直接使用缓存中的内容。 自动 选项是浏览器的默认设置,所以,几乎所有人的浏览器都是按照这种方式工作的,这个选项的作用和意义应该成为读者熟悉的重点。

不检查 选项表示浏览器不管在什么情况下访问一个页面时,只要能够在本地找到此页面的缓存信息,浏览器就不会向服务器发出访问请求,而是直接使用缓存的内容。这种设置的优点是访问效率很高,但是如果服务器端的网页内容更新后,浏览器看到的内容很可能是过期的内容。  

在浏览器的 检查所存网页的较新版本 的功能项采用默认的 自动 设置项的情况下,如果浏览器刚刚访问过一个网页,服务器端就更新了这个网页的内容,当浏览在关闭前又重新访问这个页面时,用户看到的将不是更新的网页内容,而是过期的网页内容。为了提高浏览效率,在访问静态的网页内容时,这么一点小概率的过期信息还是应该允许的,并且这些过期信息也不会造成什么不好的后果,就像你偶尔有一次看到了前一天发生的新闻,而不是当天的新闻,这又有什么问题呢?可是,如果浏览器访问的是一个动态网页,这本来就要求浏览器在其整个运行期间的每次访问都能看到最新的内容,例如,销售一件商品后再回到商品库存的显示页面时,看到的就应该是更新的库存数据,而不应该是先前看到的内容。仅仅根据被访问页面的资源名称,浏览器是无法知道商品库存的显示页面是属于动态内容,还是属于静态内容。对于这种情况,浏览器将根据响应消息中是否包含 Last-Modified 头字段来进行处理,如果响应消息中没有包含 Last-Modified 头字段,它将在每次访问此页面时都向服务器发出访问请求,否则,它仅在每次启动运行后的第一次访问此页面时才向服务器发出访问请求,而在启动运行期间对此页面的后续访问都不再向服务器发出访问请求。

响应消息中的 Last-Modified 头字段可用于指定响应内容的最后更新时间,当客户机缓存此文档内容后,它在以后的请求消息中将根据 Last-Modified 头字段指定的时间来生成 If-Modified-Since 请求头字段,以指出缓存文档的最后更新时间。只有文档的修改时间比 If-Modified-Since 请求头指定的时间新时,服务器才会返回文档内容。如果自从 If-Modified-Since 指定的时间以来,网页内容没有发生修改,服务器将返回一个 304 Not Modified )状态码来表示浏览器缓存的版本是最新的,而不会向浏览器返回文档内容,浏览器则继续使用以前缓存的内容。通过这种方式,可以在一定程度上减少浏览器与服务器之间的通信数据量,从而提高了通信效率。

HttpServlet
类为 If-Modified-Since 请求头和 Last-Modified 头字段的这种应用提供了处理机制,当继承了 HttpServlet 类的 Servlet 程序接收到一个 GET 方式的访问请求时, HttpServlet 中重载的 service 方法在调用 doGet 方法之前,它还将调用 getLastModified 方法,并根据 getLastModified 方法的返回值来决定是否调用 doGet 方法和在响应消息中是否生成 Last-Modified 头字段,具体规则如下:

getLastModified 方法返回一个负数时,不管请求消息中的情况怎样, service 方法都将直接调用 doGet 方法来生成响应内容,这正是 HTTPServlet 类中定义的 getLastModified 方法的行为;  

getLastModified 方法返回一个正数,且请求消息中没有包含 If-Modified-Since 请求头时(这往往出现在第对某个资源的第一次访问时),或者请求消息中包含的 If-Modified-Since 请求头中的时间值比 getLastModified 方法返回的时间值旧时, service 方法将根据 getLastModified 方法的返回值生成一个 Last-Modified 头字段,然后调用 doGet 方法生成响应内容;  

getLastModified 方法返回一个正数时,且请求消息中包含的 If-Modified-Since 请求头中的时间值比 getLastModified 方法返回的时间值新或者与之相同时, service 方法将不调用 doGet 方法,而是向浏览器返回一个 304 Not Modified )状态码表示浏览器可以使用其以前缓存的内容。  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值