本文介绍浏览器和Web服务器之间如何处理"浏览器缓存",以及控制缓存的http header.

本文会使用Fiddler来查看HTTP request和Response, 如果不熟悉这工具,可以先参考[Fiddler教程] 。在看本文的时候, 请务必打开Fiddler来实践。

阅读目录

  1. 缓存的概念
  2. 缓存的好处
  3. Fiddler可以方便地查看缓存的header
  4. 如何判断缓存新鲜度
  5. 通过最后修改时间,判断缓存新鲜度
  6. 与缓存相关的header
  7. ETag
  8. 浏览器不使用缓存
  9. 直接使用缓存,不去服务器端验证
  10. 如何设置IE不使用缓存
  11. 公有缓存和私有缓存的区别

缓存的概念

缓存这个东西真的是无处不在, 有浏览器端的缓存, 有服务器端的缓存,有代理服务器的缓存, 有ASP.NET页面缓存,对象缓存。 数据库也有缓存, 等等。

http中具有缓存功能的是浏览器缓存,以及缓存代理服务器。

http缓存的是指:当Web请求抵达缓存时, 如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。

缓存的好处

缓存的好处是显而易见的, 好处有,

1. 减少了冗余的数据传输,节省了网费。

2. 减少了服务器的负担, 大大提高了网站的性能

3. 加快了客户端加载网页的速度

Fiddler可以方便地查看缓存的header

Fiddler中把header都分门别类的放在一起,这样方便查看。

如何判断缓存新鲜度

Web服务器通过2种方式来判断浏览器缓存是否是最新的。

第一种, 浏览器把缓存文件的最后修改时间通过 header ”If-Modified-Since“来告诉Web服务器。

第二种, 浏览器把缓存文件的ETag, 通过header "If-None-Match", 来告诉Web服务器。

通过最后修改时间, 来判断缓存新鲜度

1. 浏览器客户端想请求一个文档,  首先检查本地缓存,发现存在这个文档的缓存,  获取缓存中文档的最后修改时间,通过: If-Modified-Since, 发送Request给Web服务器。

2. Web服务器收到Request,将服务器的文档修改时间(Last-Modified): 跟request header 中的,If-Modified-Since相比较, 如果时间是一样的, 说明缓存还是最新的, Web服务器将发送304 Not Modified给浏览器客户端, 告诉客户端直接使用缓存里的版本。如下图。

3. 假如该文档已经被更新了。Web服务器将发送该文档的最新版本给浏览器客户端, 如下图。

实例: 打开Fiddler, 然后打开博客园首页。然后F5刷新几次浏览器。 你会看到博客园首页也用了缓存。

与缓存有关的header

我们来看看每个header的具体含义。

Request

Cache-Control: max-age=0 以秒为单位
If-Modified-Since: Mon, 19 Nov 2012 08:38:01 GMT 缓存文件的最后修改时间。
If-None-Match: "0693f67a67cc1:0" 缓存文件的Etag值
Cache-Control: no-cache 不使用缓存
Pragma: no-cache 不使用缓存
   

Response

Cache-Control: public 响应被缓存,并且在多用户间共享,  (公有缓存和私有缓存的区别,请看另一节
Cache-Control: private 响应只能作为私有缓存,不能在用户之间共享
Cache-Control:no-cache 提醒浏览器要从服务器提取文档进行验证
Cache-Control:no-store 绝对禁止缓存(用于机密,敏感文件)
Cache-Control: max-age=60 60秒之后缓存过期(相对时间)
Date: Mon, 19 Nov 2012 08:39:00 GMT 当前response发送的时间
Expires: Mon, 19 Nov 2012 08:40:01 GMT 缓存过期的时间(绝对时间)
Last-Modified: Mon, 19 Nov 2012 08:38:01 GMT 服务器端文件的最后修改时间
ETag: "20b1add7ec1cd1:0" 服务器端文件的Etag值

如果同时存在cache-control和Expires怎么办呢?
浏览器总是优先使用cache-control,如果没有cache-control才考虑Expires

ETag

ETag是实体标签(Entity Tag)的缩写, 根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果),可以标识资源的状态。 当资源发送改变时,ETag也随之发生变化。

ETag是Web服务端产生的,然后发给浏览器客户端。浏览器客户端是不用关心Etag是如何产生的。

为什么使用ETag呢? 主要是为了解决Last-Modified 无法解决的一些问题。

1. 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了。

2. 某些文件的修改非常频繁,在秒以下的时间内进行修改. Last-Modified只能精确到秒。

3. 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了。

实例, 打开Fiddler, 打开博客园首页。  你可以看到很多图片,或者CSS文件都是用了缓存。 这些都是通过比较ETag的值,来判断文件是否更新了。

浏览器不使用缓存

CTRL+F5强制刷新浏览器,或者设置IE。  可以让浏览器不使用缓存。

1. 浏览器发送Http request, 给Web 服务器, header中带有Cache-Control: no-cache.   明确告诉Web服务器,客户端不使用缓存。

2. Web服务器将把最新的文档发送给浏览器客户端.

实例:

打开Fiddler, 打开博客园首页, 然后按CTRL+F5强制刷新浏览器,你将看到

Pragma: no-cache的作用和Cache-Control: no-cache一模一样。 都是不使用缓存。

Pragma: no-cache 是HTTP 1.0中定义的, 所以为了兼容HTTP 1.0. 所以会同时使用Pragma: no-cache和Cache-Control: no-cache

直接使用缓存,不去服务器验证

按F5刷新浏览器和在地址栏里输入网址然后回车。 这两个行为是不一样的。

按F5刷新浏览器, 浏览器会去Web服务器验证缓存。

如果是在地址栏输入网址然后回车,浏览器会"直接使用有效的缓存", 而不会发http request 去服务器验证缓存,这种情况叫做缓存命中,如下图

实例: 比较第一次访问博客园主页和第二次博客园主页

1. 启动Fiddler, 用firefox打开博客园主页, 发现有50多个session。

2. 按CTRL+X将Fiddler中的所有session删除。 关闭firefox,重新打开一个firefox,打开博客园主页。   发现只有30多个session.

分析;  少了的session是因为firefox直接用了缓存,而没有发http request。

如何设置IE不使用缓存

打开IE。点击工具栏上的, 工具->Internet选项->常规->浏览历史记录 设置. 选择“从不”。然后保存。

然后点击“删除”  把Internet临时文件都删掉 (IE缓存的文件就是Internet临时文件)。

公有缓存和私有缓存的区别

Cache-Control: public 指可以公有缓存, 可以是数千名用户共享的。

Cache-Control: private 指只支持私有缓存, 私有缓存是单个用户专用的。

HTTP协议学习---(六)缓存的更多相关文章

  1. TCP/IP协议学习(六) 链路层详解

    学习知识很简单,但坚持不懈却又是如此的困难,即使一直对自己说"努力,不能停下"的我也慢慢懈怠了... 闲话不多说,本篇将讲述TCP/IP协议栈的链路层.在本系列第一篇我讲到,TCP ...

  2. TCP/IP协议学习之实例ping命令学习笔记

    TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...

  3. http协议学习系列

    深入理解HTTP协议(转)  http://www.blogjava.net/zjusuyong/articles/304788.html http协议学习系列   1. 基础概念篇 1.1 介绍 H ...

  4. Hbase深入学习(六) Java操作HBase

    Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...

  5. HTTP协议学习笔记(四)

    HTTP协议学习笔记(四) 与 HTTP 协作的 Web 服务器 一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路径上的中转服务器提升传输效率. 1.用单台虚拟主机实现多个域名 ...

  6. 苹果ANCS协议学习【转】

    苹果ANCS协议学习 转自:http://www.cnblogs.com/alexcai/p/4321514.html 综述 苹果通知中心(Apple Notification Center Serv ...

  7. http协议学习系列(一个博文链接)

    深入理解HTTP协议(转) http协议学习系列(转自:http://www.blogjava.net/zjusuyong/articles/304788.html) 1. 基础概念篇 1.1 介绍 ...

  8. 转 #HTTP协议学习# (一)request 和response 解析

    http://www.cnblogs.com/bukudekong/p/3834020.html #HTTP协议学习# (一)request 和response 解析   注:本文转自:http:// ...

  9. 转:http协议学习系列(响应头---Response Headers)

    HTTP最常见的响应头如下所示: ·Allow:服务器支持哪些请求方法(如GET.POST等): ·Content-Encoding:文档的编码(Encode)方法.只有在解码之后才可以得到Conte ...

  10. TCP/IP协议学习(五) 基于C# Socket的C/S模型

    TCP/IP协议作为现代网络通讯的基石,内容包罗万象,直接去理解理论是比较困难的:然而通过实践先理解网络通讯的理解,在反过来理解学习TCP/IP协议栈就相对简单很多.C#通过提供的Socket API ...

随机推荐

  1. ACCP7.0优化Myschool内侧题

    1) 在SQL Server 中,为数据库表建立索引能够(C ). 索引:是SQL SERVER编排数据的内部方法,是检索表中数据的直接通道 建立索引的作用:大大提高了数据库的检索速度,改善数据库性能 ...

  2. 微软前 CEO 史蒂姆·鲍尔默:除了我们没人拼得过苹果硬件

    微软通过 Surface Book 正式宣布进军笔记本电脑行业的同时,宣传语表示 Surface Book“比苹果的 MacBook Pro 还要快两倍”. 业界对 Surface Book 的好评连 ...

  3. iOS本地化

    本地化与相机中显示英文  工程PROJECT -> info ->Localizations 添加相应的国际化语言  一.当你发现相机中显示英文,可以通过它设置 添加一项“Localize ...

  4. tomcat相关配置技巧梳理

    tomcat常用架构:1)nginx+tomcat:即前端放一台nginx,然后通过nginx反向代理到tomcat端口(可参考:分享一例测试环境下nginx+tomcat的视频业务部署记录)2)to ...

  5. 定时取数据库的schema,并推送到git服务器

    写了个脚本,定时去数据库取schema,并推送到公司的git里. #daily_schema.py #/usr/bin/env python import os import datetime,tim ...

  6. IntelliJ Idea14 创建Maven多模块项目

    Maven多模块项目的参考资料 Sonatype上的教程 http://books.sonatype.com/mvnex-book/reference/multimodule.html 在这个教程里, ...

  7. MIPAV - Talairach ACPC transform

    源地址:http://blog.sina.com.cn/s/blog_64cfe24f0100h358.html 1.打开MIPAV软件,File>open image from disk> ...

  8. 准备NOIP2017 最长公共子序列(模版)

    一些概念: (1)子序列: 一个序列A = a1,a2,--an,中任意删除若干项,剩余的序列叫做A的一个子序列.也可以认为是从序列A按原顺序保留任意若干项得到的序列.例如:   对序列 1,3,5, ...

  9. salt yum安装lamp

    在批量安装软件前,先找台测试机yum装一遍,看是否报错等,是否依赖包全等 .         本次我们在dev环境下搞. 先看一下已搞成功的目录结构         定义dev环境的第二个好处     ...

  10. ORA-06519: active autonomous transaction detected and rolled back

    这个问题一般怎么解决 ?现在忙 待会贴详细代码  先给些路子..给位大大们 引用 楼主 green3365302 的回复: 这个问题一般怎么解决 ?现在忙 待会贴详细代码  先给些路子..给位大大们 ...