从敲入 URL 到浏览器渲染完成、对HTTP协议的理解
1. 大致过程
当你这样子回答的时候:
-
用户输入 url 地址,浏览器查询 DNS 查找对应的请求 IP 地址
-
建立 TCP 连接
-
浏览器向服务器发送 http 请求,如果服务器段返回以 301 之类的重定向,浏览器根据相应头中的 location 再次发送请求
-
服务器端接受请求,处理请求生成 html 代码,返回给浏览器,这时的 html 页面代码可能是经过压缩的
-
浏览器接收服务器响应结果,如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
-
解析该过程分为:解析 HTML,构建 DOM 树,DOM 树与 CSS 样式进行附着构造呈现树,布局、绘制
虽然这大致的过程是对的,但回答不上细节 !深度不够!!!
2. 详细过程
2.1 输入地址
浏览器引入了 DNS 预取技术。它是利用现有的 DNS 机制,提前解析网页中可能的网络连接。
当我们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了。它会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url ,找到同输入的地址很匹配的项,然后给出智能提示,让你可以补全 url 地址。用户还没有按下 enter 键, 浏览器已经开始使用 DNS 预取技术解析该域名了。
对于 chrome 的浏览器,如果有该域名相关的缓存,它会直接从缓存中把网页展示出来,就是说,你还没有按下 enter,页面就出来了。如果没有缓存,就还是会重新请求资源。
2.2 查询 DNS 查找对应的请求 IP 地址
假设输入 www.baidu.com,大概过程:
-
浏览器搜索自己的 DNS 缓存。
-
在浏览器缓存中没找到,就在操作系统缓存中查找,这一步中也会查找本机的 hosts 看看有没有对应的域名映射。
-
在系统中也没有的话,就到你的路由器来查找,因为路由器一般也会有自己的 DNS 缓存。
-
若没有,则操作系统将域名发送至 本地域名服务器——递归查询方式,本地域名服务器 查询自己的 DNS 缓存,查找成功则返回结果,否则,采用迭代查询方式。本地域名服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
-
本地域名服务器 将得到的 IP 地址返回给操作系统,同时自己也将 IP 地址缓存起来。
-
操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
-
至此,浏览器已经得到了域名对应的 IP 地址。
参考文章:
https://blog.csdn.net/wlk2064819994/article/details/79756669
https://blog.csdn.net/dojiangv/article/details/51794535
2.3 建立 TCP 连接
TCP 是一种面向有连接的传输层协议。
它可以保证两端(发送端和接收端)通信主机之间的通信可达。
它能够处理在传输过程中丢包、传输顺序乱掉等异常情况;此外它还能有效利用宽带,缓解网络拥堵。
三次握手的步骤:(抽象派)
客户端:hello,你是server么?
服务端:hello,我是server,你是client么
客户端:yes,我是client
在 TCP 连接建立完成之后就可以发送 HTTP 请求了。
然后,待到断开连接时,需要进行四次挥手(因为是全双工的,所以需要四次挥手)
四次挥手的步骤:(抽象派)
主动方:我已经关闭了向你那边的主动通道了,只能被动接收了
被动方:收到通道关闭的信息
被动方:那我也告诉你,我这边向你的主动通道也关闭了
主动方:最后收到数据,之后双方无法通信
2.4 服务器收到请求并响应 HTTP 请求
在接收和解释请求消息后,服务器返回一个HTTP响应消息。
HTTP 响应由三个部分组成,分别是:状态行、消息报头、响应正文。
状态代码:由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:
- 1xx:指示信息--表示请求已接收,继续处理
- 2xx:成功--表示请求已被成功接收、理解、接受
- 3xx:重定向--要完成请求必须进行更进一步的操作
- 4xx:客户端错误--请求有语法错误或请求无法实现
- 5xx:服务器端错误--服务器未能实现合法的请求
常见状态代码、状态描述、说明:
- 200 OK :客户端请求成功
- 400 Bad Request :客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized :请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden :服务器收到请求,但是拒绝提供服务
- 404 Not Found :请求资源不存在,eg:输入了错误的URL
- 500 Internal Server Error :服务器发生不可预期的错误
- 503 Server Unavailable :服务器当前不能处理客户端的请求,一段时间后可能恢复正常
HTTP消息报头包括:普通报头、请求报头、响应报头、实体报头。具体不作介绍。
响应正文:就是服务器返回的资源的内容
2.5 浏览器接收服务器响应结果并处理
在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了,不同浏览器可能解析的过程不太一样,这里我们只介绍 WebKit 的渲染过程。
渲染步骤大致可以分为以下几步:
1. 解析HTML,构建 DOM 树
2. 解析 CSS ,生成 CSS 规则树
3. 合并 DOM 树和 CSS 规则,生成 render 树
4. 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
5. 绘制 render 树( paint ),绘制页面像素信息
6. 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成( composite ),显示在屏幕上
其中每个解释的过程中,WebKit 都提供了很多相关的类来一步一步地解释对应的内部模块,这里面不做详细描述。
下面根据上面的大致过程来一步步细解。
2.5.1 构造 DOM 树
浏览器在解析html文件时, 是WebKit 中的 HTML 解释器的将网络或者本地磁盘获取的 HTML 网页和资源从字节流解释成 DOM 树结构。具体过程如下 :
在 WebKit 中这一过程如下:首先是字节流,经过解码之后是字符流,然后通过词法分析器会被解释成词语(Tokens),之后经过语法分析器构建成节点,最后这些节点被组建成一棵 DOM 树。
浏览器在解析html文件过程中,会 ”自上而下“ 加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载,且统一交由 Browser 进程来处理,这使得资源在不同网页间的共享变得很容易。
HTML 的解释、布局和渲染等工作基本上就是工作在渲染线程完成的(这不是绝对的)。因为 DOM 树只能在渲染线程上创建和访问,这也就是说构建 DOM 树的过程只能在渲染线程中进行,但是,从字符到词语这个阶段可以交给另外的单独的线程来做。
而且因为有 DNS 预取技术,当用户正在浏览当前网页的时候,Chromium 提取网页中的超链接,将域名抽取出来,利用比较少的 CPU 和网络带宽来解析这些域名或者 IP 地址,这样一来,用户根本感觉不到这一过程。当用户单击这些链接的时候,可以节省不少时间,特别在域名解析比较慢的时候,效果特别明显。
解析过程中,浏览器首先会解析 HTML 文件构建 DOM 树,然后解析 CSS 文件构建 Render树,等到 Render 树构建完成后,浏览器开始布局 Render 树并将其绘制到屏幕上。
2.5.2 解释 CSS
CSS 解释过程是指从 CSS 字符串 经过 CSS 解释器 处理后变成渲染引擎内部规则的表示过程。
生成样式规则之后,会进行样式规则匹配,WebKit 会为其中的一些节点(只限于可视节点)选择合适的样式信息,规则的匹配则是由 ElementRuleCollector 类来计算并获得,它根据元素的属性等,并从 DocumentRuleSets 类中获取规则集合,依次按照 ID、类别、标签等选择器信息逐次匹配获得元素的样式。
最后,WebKit 对这些规则进行排序。对于该元素需要的样式属性,WebKit 选择从高优先级规则中选取,并将样式属性值返回。
从整个网页的加载和渲染过程来看,CSS 解释和规则匹配处于 DOM 树建立之后,RenderObject 树建立之前,CSS 解释器解释后的结果会保存起来,然后 RenderObject 树基于该结果来进行规范匹配和布局计算。当网页有用户交互或者动画等动作的时候,通过 CSSDOM 等技术,JavaScript 代码同样可以非常方便地修改 CSS 代码,WebKit 此时需要重新解释样式并重复以上这一过程。
2.5.3 渲染过程遇到 JavaScript
当文档加载过程中遇到 js 文件,html 文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中 js 文件加载完毕,还要等待解析执行完毕,才可以恢复 html 文档的渲染线程。因为 JS 有可能会修改 DOM,最为经典的 document.write,这意味着,在 JS 执行完成前,后续所有资源的下载可能是没有必要的,这是 js 阻塞后续资源下载的根本原因。所以我们平时的代码中,js 是放在 html 文档末尾的。
而且当遇到执行 JavaScript 代码的时候,WebKit 先暂停当前 JavaScript 代码的执行,使用预先扫描器 HTMLPreloadScanner 类来扫描后面的词语。如果 WebKit 发现它们需要使用其他资源,那么使用预资源加载器 HTMLPreloadScanner 类来发送请求,在这之后,才执行 JavaScript 代码。预先扫描器本身并不创建节点对象,也不会构建 DOM 树,所以速度比较快。
当 DOM 树构建完之后,WebKit 触发 “DOMContentLoaded” 事件,注册在该事件上的 JavaScript 函数会被调用。当所在资源都被加载完之后,WebKit 触发 “onload” 事件。
WebKit 将 DOM 树创建过程中需要执行的 JavaScript 代码交由 HTMLScriptRunner 类来负责。工作方式很简单,就是利用 JavaScript 引擎来执行 Node 节点中包含的代码。
JS 的解析是由浏览器中的 JavaScript 引擎完成的。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如 IO 读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。
JS 的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务是放在任务队列中的任务。所有的同步任务在主线程上执行,形成一个执行栈; 异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后会从任务队列里提取事件,运行任务队列中的任务,这个过程是不断重复的,所以又叫做事件循环(Event loop)。
2.5.4 渲染合成 Render 树
HTML 经过 WebKit 解释之后,生成 DOM 树。在 DOM 树构建完成之后,WebKit 会为 DOM 树节点构建 RenderObject 树,再通过 RenderObject 树构建出 RenderLayer 树。
RenderObject 树是基于 DOM 树建立起来的一棵新树,是为了布局计算和渲染等机制而构建的一种新的内部表示。RenderObject 树节点和 DOM 节点不是一一对应关系,因为有可视节点(常用的 div img 标签等)与不可视节点(如 head、meta 标签),不可视节点是不会构成 RenderObject 树的。
网页是有层次结构的,可以分层的,一是为了方便设置网页的层次,二是为了 WebKit 处理上的便利,为了简化渲染的逻辑。
而且 RenderLayer 节点和 RenderObject 节点不是一一对应关系,而是一对多的关系。
2.5.5 布局
当 WebKit 创建 RenderObject 对象之后,每个对象是不知道自己的位置、大小等信息的,WebKit 根据框模型来计算它们的位置,大小等信息的过程称为布局计算。
布局计算是一个递归的过程,因为一个节点的大小通常需要先计算它的子女节点的位置,大小等信息。
当用户 网页的动画、翻滚网页、JavaScript 代码通过 CSSDOM 等操作时还会有重新布局。
2.5.6 绘图
在 WebKit 中,绘图操作就是绘图上下文,所有绘图的操作都是在该上下文中来进行的。
绘图上下文可以分成两种类型:
一是 2D 图形上下文(GraphicsContext),用来绘制 2D 图形的的上下文;
二是 3D 绘图上下文,是用来绘制 3D 图形的上下文。
2D 绘图上下文具体的作用:提供基本绘图单元的绘制接口以及设置绘图的样式。绘图接口包括画点,画线、画图片、画多边形、画文字等,绘图样式包括颜色、线宽、字号大小、渐变等。
关于 3D 绘图上下文,它的主要用处是支持 CSS3D、WebGL 等。
网页的渲染方式,有三种方式,一是软件渲染,二是硬件加速渲染,三可以说是混合模式。
如果绘图操作使用 CPU 来完成,称之为软件绘图。
如果绘图操作由 GPU 来完成,称之为 GPU 硬件加速绘图。
理想情况下,每个层都有个绘制的存储区域,这个存储区域用来保存绘图的结果。最后,需要将这些层的内容合并到同一个图像之中,可以称之为合成(Compositing),使用了合成技术的渲染称之为合成化渲染。
所以,在完成构建 DOM 树之后,WebKit 会调用绘图操作、软件渲染或者硬件加速渲染或者两者都有,将模型绘制出来,呈现在屏幕上。
至此,浏览器渲染完成。
以上转载自 http://biaochenxuying.cn/articleDetail?article_id=5bf4bb59245730373274df64
什么是HTTP?
HTTP(超文本传输协议)是应用层上的一种客户端/服务端模型的通信协议,协议规定了通信双方必须遵循的数据传输格式,这样通信双方按照约定的格式才能准确的通信。它由请求和响应构成,且是无状态的。无状态是指两次连接通信之间是没有任何关系的,每次都是一个新的连接,服务端不会记录前后的请求信息,就是说你之前的请求并不会被知晓,可以理解为‘活在当下’。
HTTP由五层协议组成:
HTTP(应用层),TCP(传输层),IP(网络层),数据链路(链路层),物理介质(物理层)
URL的构成:
例如:http(https)://www.baidu.com/index?firstname=yf&lastname=song#mao 中 http(https)-协议 www.baidu.com-域名,由dns服务器找到hostIP地址 ,?之后为参数,以&分隔,#为锚链接,锚链接不会发起新请求
协议内容:
请求request:包括请求行、请求头、请求体
例如:
(如何查看? 浏览器F12->XHR->Headers)
响应response:包括状态行、响应头、响应体
状态码:
HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:
1**:服务器收到请求,需要请求者继续操作 2**:操作成功接收并处理 3**:重定向 4**:客户端错误 5**:服务器错误
常见的包括:200请求成功,301重定向,400请求语义有误,401请求需要用户验证,403请求被服务器主动拒绝,404请求找不到所需要的资源,500服务器错误,502服务器作为网关得到错误响应
请求方法:
GET:请求指定的页面信息,并返回实体主体。
HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
PUT:从客户端向服务器传送的数据取代指定的文档的内容。
DELETE:请求服务器删除指定的页面。
CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS:允许客户端查看服务器的性能。
TRACE:回显服务器收到的请求,主要用于测试或诊断。
最常见的就是GET、POST方法(即RPC风格),比较古老的基于浏览器的客户端只支持get,post,而在RESTful架构中通过GET,DELETE,PUT和POST实现了表述性状态转移,RESTful架构遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。避免了URI使用动作来描述,如[GET]localhost:5000/delete?name=zhangsan,而是[DELETE] localhost:5000/name/zhangsan
HTTP通用头 通用头域包含请求和响应消息都支持的头域,通用头域包含缓存头部Cache-Control、Pragma及信息性头部Connection、Date、Transfer-Encoding、Update、Via。 1、Cache-Control Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、 max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下: no-cache:指示请求或响应消息不能缓存,实际上是可以存储在本地缓存区中的,只是在与原始服务器进行新鲜度验证之前,缓存不能将其提供给客户端使用。 no-store:缓存应该尽快从存储器中删除文档的所有痕迹,因为其中可能会包含敏感信息。 max-age:缓存无法返回缓存时间长于max-age规定秒的文档,若不超规定秒浏览器将不会发送对应的请求到服务器,数据由缓存直接返回;超过这一时间段才进一步由服务器决定是返回新数据还是仍由缓存提供。若同时还发送了max-stale指令,则使用期可能会超过其过期时间。 min-fresh:至少在未来规定秒内文档要保持新鲜,接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象。 max-stale:指示客户端可以接收过期响应消息,如果指定max-stale消息的值,那么客户端可以接收过期但在指定值之内的响应消息。 only-if-cached:只有当缓存中有副本存在时,客户端才会获得一份副本。 Public:指示响应可被任何缓存区缓存,可以用缓存内容回应任何用户。 Private:指示对于单个用户的整个或部分响应消息,不能被共享缓存处理,只能用缓存内容回应先前请求该内容的那个用户。 2、Pragma Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。 3、Connection Connection表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。 Close:告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了。 Keepalive:告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求。 Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒),如Keep-Alive:300。 4、Date Date头域表示消息发送的时间,服务器响应中要包含这个头部,因为缓存在评估响应的新鲜度时要用到,其时间的描述格式由RFC822定义。例如,Date:Mon, 31 Dec 2001 04:25:57 GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。 5、Transfer-Encoding WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked),例如:Transfer-Encoding: chunked 6、Upgrade 它可以指定另一种可能完全不同的协议,如HTTP/1.1客户端可以向服务器发送一条HTTP/1.0请求,其中包含值为“HTTP/1.1”的Update头部,这样客户端就可以测试一下服务器是否也使用HTTP/1.1了。 7、Via 列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。 当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器 收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。例如:Via:1.0 236-81.D07071953.sina.com.cn:80 (squid/2.6.STABLE13) HTTP请求头 请求头用于说明是谁或什么在发送请求、请求源于何处,或者客户端的喜好及能力。服务器可以根据请求头部给出的客户端信息,试着为客户端提供更好的响应。请求头域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If-Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、Proxy-Authorization、Range、Referer、User-Agent。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为实体头域处理。 8、Accept 告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。 9、Accept-Charset 浏览器告诉服务器自己能接收的字符集。 10、Accept-Encoding 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)。 11、Accept-Language 浏览器申明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等。 12、Authorization 当客户端接收到来自WEB服务器的 WWW-Authenticate 响应时,用该头部来回应自己的身份验证信息给WEB服务器。 13、If-Match 如果对象的 ETag 没有改变,其实也就意味著对象没有改变,才执行请求的动作,获取文档。 14、If-None-Match 如果对象的 ETag 改变了,其实也就意味著对象也改变了,才执行请求的动作,获取文档。 15、If-Modified-Since 如果请求的对象在该头部指定的时间之后修改了,才执行请求的动作(比如返回对象),否则返回代码304,告诉浏览器该对象没有修改。例如:If-Modified-Since:Thu, 10 Apr 2008 09:14:42 GMT 16、If-Unmodified-Since 如果请求的对象在该头部指定的时间之后没修改过,才执行请求的动作(比如返回对象)。 17、If-Range 浏览器告诉 WEB 服务器,如果我请求的对象没有改变,就把我缺少的部分给我,如果对象改变了,就把整个对象给我。浏览器通过发送请求对象的ETag 或者自己所知道的最后修改时间给 WEB 服务器,让其判断对象是否改变了。总是跟 Range 头部一起使用。 18、Range 浏览器(比如 Flashget 多线程下载时)告诉 WEB 服务器自己想取对象的哪部分。例如:Range: bytes=1173546 19、Proxy-Authenticate 代理服务器响应浏览器,要求其提供代理身份验证信息。 20、Proxy-Authorization 浏览器响应代理服务器的身份验证请求,提供自己的身份信息。 21、Host 客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号。如Host:rss.sina.com.cn 22、Referer 浏览器向WEB 服务器表明自己是从哪个网页URL获得点击当前请求中的网址/URL,例如:Referer:http://www.jb51.net 23、User-Agent 浏览器表明自己的身份(是哪种浏览器)。例如:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN;rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14
HTTP响应头 响应头向客户端提供一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些头部有助于客户端处理响应,并在将来发起更好的请求。响应头域包含Age、Location、Proxy-Authenticate、Public、Retry- After、Server、Vary、Warning、WWW-Authenticate。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。 24、Age 当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了。 25、Server WEB 服务器表明自己是什么软件及版本等信息。例如:Server:Apache/2.0.61 (Unix) 26、Accept-Ranges WEB服务器表明自己是否接受获取其某个实体的一部分(比如文件的一部分)的请求。bytes:表示接受,none:表示不接受。 27、Vary WEB服务器用该头部的内容告诉 Cache 服务器,在什么条件下才能用本响应所返回的对象响应后续的请求。假如源WEB服务器在接到第一个请求消息时,其响应消息的头部为:Content-Encoding: gzip; Vary: Content-Encoding,那么Cache服务器会分析后续请求消息的头部,检查其Accept-Encoding,是否跟先前响应的Vary头部值一致,即是否使用相同的内容编码方法,这样就可以防止Cache服务器用自己Cache 里面压缩后的实体响应给不具备解压能力的浏览器。例如:Vary:Accept-Encoding。 HTTP实体头 实体头部提供了有关实体及其内容的大量信息,从有关对象类型的信息,到能够对资源使用的各种有效的请求方法。总之,实体头部可以告知接收者它在对什么进行处理。请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,实体头包括信息性头部Allow、Location,内容头部Content-Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type,缓存头部Etag、Expires、Last-Modified、extension-header。 28、Allow 服务器支持哪些请求方法(如GET、POST等)。 29、Location 表示客户应当到哪里去提取文档,用于将接收端定位到资源的位置(URL)上。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 30、Content-Base 解析主体中的相对URL时使用的基础URL。 31、Content-Encoding WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip 32、Content-Language WEB 服务器告诉浏览器理解主体时最适宜使用的自然语言。 33、Content-Length WEB服务器告诉浏览器自己响应的对象的长度或尺寸,例如:Content-Length: 26012 34、Content-Location 资源实际所处的位置。 35、Content-MD5 主体的MD5校验和。 36、Content-Range 实体头用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式: Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth。例如,传送头500个字节次字段的形式:Content-Range:bytes0- 499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范围,Content-Length表示实际传送的字节数。 37、Content-Type WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml 38、Etag 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对比,然后就知道这个文件有没有改变了。 39、Expires WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT 40、Last-Modified WEB服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT