前言关于HTTP的知识比较繁杂,也比较零散,于是想要通过这篇文章对常用知识点进行总结,一些知识点描述是从网上搜集而来,如有侵权,可以联系我进行修改。提出问题Http的报文结构。Http request的几种类型。Http的状态码含义。Http1.1和Http1.0的区别,以及缓存原理Http长连接keep-alive。Cookie与Session的作用于原理。电脑上访问一个网页,整个过程是怎么样的:DNS、HTTP、TCP、OSPF、IP、ARP。解答1. Http的报文结构http协议的请求报文和响应报文都是由以下4部分组成:请求行请求头空行 CR + LF,回车 + 换行请求体2. Http request的几种类型请求行Request格式:【方法 URL HTTP版本】 例如: GET /csrfToken HTTP/1.1HTTP版本:目前有 HTTP/1.0、HTTP/1.1、HTTP/2.0 版本,其中 HTTP1.1 版本使用较广泛方法说明支持HTTP协议版本GET获取资源1.0 、1.1POST传输实体主体1.0、1.1PUT传输文件1.0、1.1HEAD获得报文首部1.0、1.1DELETE删除资源1.0、1.1OPTIONS询问支持的方法1.1TRACE追踪路径1.1CONNECT要求用隧道协议连接代理1.1LINK建立和资源之间的联系1.0UNLINK断开连接关系1.0Response格式:【HTTP版本 状态码 描述】 例如: HTTP/1.1 200 OK、HTTP/1.1 404 NOT FOUND 类别原因短语1xxInformational(信息性状态码)接收的请求正在处理2xxSuccess(成功状态码)请求正常处理完毕3xxRedirection(重定向状态码)需要进行附加操作以完成请求4xxClient Error(客户端错误状态码)服务器无法处理请求5xxServer Error(服务器错误状态码)服务器处理请求出错3. Http的状态码含义常用状态码200:OK,请求被正常处理204:No Content,请求被受理但没有资源可以返回,返回204响应,浏览器显示的页面不发生更新206:Partial Content,客户端进行范围请求,服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容301:Moved Permanently,永久性重定向,比如访问http://test.zhixue.com/zbptadmin,服务器会返回301,response的headers中会包含一个字段:Location: http://test.zhixue.com/zbptadmin/,浏览器会按照这个地址重新请求,并且如果用户保存了书签,浏览器会自动按照Location更新书签302:Found,临时性重定向,和301类似,但是浏览器不会更新书签303:See Other,和302类似,但303明确表示客户端应该使用GET方法获取Location资源备注:当301,302,303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301,302标准是禁止将POST方法改成GET方法的,但实际使用时浏览器厂商都会这么做。304:Not Modified,发送附带条件的请求时,(附带条件的请求是指采用GET方法的请求报文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部),条件不满足返回304,可直接使用客户端缓存,与重定向无关307:Temporary Redirect,临时重定向,与302类似,只是强制要求使用POST方法400:Bad Request,请求报文中存在语法错误,服务器无法识别401:Unauthorized,请求需要认证403:Forbidden,请求对应的资源禁止被访问404:Not Found,服务器无法找到对应资源500:Internal Server Error,服务器内部错误503:Service Unavailable,服务器正忙常见HTTP首部字段通用首部字段(请求报文与响应报文都会使用的首部字段)Date:创建报文的时间Connection:连接的管理Cache-Control:缓存的控制Transfer-Encoding:报文主题的传输编码方式请求首部字段(请求报文会使用的首部字段)Host:请求资源所在的服务器Accept:可处理的媒体类型Accept-Charset:可接收的字符集Accept-Encoding:可接收的内容编码Accept-Language:可接收的自然语言响应首部字段(响应报文会使用的首部字段)Accept-Range:可接收的字节范围Location:让客户端重定向到的URIServer:HTTP服务器的安装信息实体首部字段(请求报文与响应报文的实体部分使用的首部字段)Allow:资源可支持的HTTP方法Content-Type:实体主类的类型Content-Encoding:实体主体适用的编码方式Content-Language:实体主体的自然语言Content-Length:实体主体的字节数Content-Range:实体主体的位置范围,一般用于发出部分请求时使用4. HTTP1.0、HTTP1.1、HTTP2.0区别HTTP1.0 和 HTTP1.1 主要区别长连接HTTP1.0需要使用keep-alive参数告知服务器要建立一个长连接,而HTTP1.1默认支持长连接HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用这个长连接来发送多个请求节约带宽HTTP1.1支持只发送header信息,也就是HTTP的HEAD Method,如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接收到100,才开始把请求体body发送到服务器。这样,当服务器返回401的时候,客户端就可以不用发送请求体了,节约了带宽HTTP1.1支持分块传输,比如206状态码,由Content-Range指定传输内容,这是支持文件断点续传的基础。HOST域现在一台服务器上可以有多个虚拟主机,这些虚拟站点可以共享同一个ip和端口,HTTP1.0是没有host域的,HTTP1.1才支持这个参数HTTP1.1 和 HTTP2.0的区别多路复用HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级当然HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立的连接,并且这个连接可以支持瞬时并发的请求HTTP/1.1,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某个请求超时,后续请求只能被阻塞,也就是人们常说的线头阻塞HTTP/2.0,多个请求可同时在一个连接上并行执行,某个任务耗时严重,不会影响到其他连接的正常执行数据压缩HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快服务器推送当我们对HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器获取。这种方式非常适合加载静态资源。服务器推送的这些资源其实存在客户端的某个地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然快很多。HTTP缓存缓存分类强缓存浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器,此时状态码是200,但是看Size项是from memory cache或from disk cache协商缓存当强缓存没有命中时,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果命中,服务器会将这个请求返回304,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器就又会从自己的缓存中去加载这个资源;如果没有命中,则将资源返回客户端,状态为200,浏览器同时依据response header中的相关项更新本地缓存数据from memory cache 和 from disk cache区别from memory cache 是从内存中读取缓存资源,很快,关闭浏览器后,内存中的资源就消失了from disk cache 是从磁盘中读取缓存资源,要比 from memory cache 慢,但是持久化,关闭浏览器后仍然存在哪些资源存在memory,哪些资源存在disk看了一些文章,大部分观点是说:资源在disk和memory中都会存当关闭浏览器,再打开那个页面的时候,从disk cache中获取缓存资源,同时将缓存资源存在了内存中,当再次刷新页面的时候,就从memory cache中读取,因为这样会更快一些我自己试了一些页面,再次刷新还是有的from disk cache,有的from memory cache,所以这个持保留观点还有的文章说css文件存在disk中,js等脚本存在memory中,个人认为这个不太靠谱,因为memory中的缓存在关闭浏览器就消失了,如果js只存在memory,就起不到缓存的作用了强缓存相关http headerExpiresExpires的值是服务端返回的到期时间,用GMT格式的字符串表示,如:Expires: Thu, 31 Dec 2016 23:55:55 GMT。即下一次请求时,请求时间小于服务器返回的到期时间,直接使用缓存数据。不过Expires是HTTP1.0的东西,现在浏览器默认使用HTTP1.1,所以它的作用基本忽略。另一个问题是,到期时间是由服务器生成的,但是客户端时间可能和服务器时间有偏差,这就会导致缓存命中的误差。所以HTTP1.1的版本中,使用Cache-Control替代。Cache-ControlCache-Control是最重要的规则。常见的取值有:- private
:客户端可以缓存- public
:客户端和代理服务器都可以缓存- max-age=xxx
:缓存的内容将在xxx秒后失效,单位是秒- no-cache
:需要使用协商缓存来验证缓存数据- no-store
:不缓存协商缓存相关http header第1组:Last-Modified/If-Modified—SinceLast-Modified:第一次请求资源时,服务器返回的http header,告诉浏览器资源的最后修改时间,为GMT格式,如Last-Modified: Thu, 24 Jan 2017 23:55:55 GMTIf-Modified-Since:再次请求服务器资源时,浏览器设置在请求header中,值 为该资源第一次请求时服务器设置的Last-Modified`值,如If-Modified-Since: Thu, 24 Jan 2017 23:55:55 GMT,服务器收到请求后发现request header中有If-Modified-Since,则与被请求资源的最后修改时间进行比对。若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则返回状态码304,但是不返回资源,告知浏览器继续使用所保存的cache第2组:Etag/If-None-MatchEtag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器确定),如Etag: W/“5886c231-8d9"If-None-Match:再次请求服务器时,通过此字段告知服务器该资源的唯一标识,如If-None-Match: W/“5886c231-8d9”,服务器收到请求后发现request header中有If-None-Match,则与被请求资源的唯一标识进行比对,若不同,说明资源又被改动过,则返回资源内容,状态码200,同时浏览器依据相应response header更新缓存资源;若相同,则说明资源无更改,返回304,告知浏览器继续使用所保存的缓存资源为什么要有Etag?Last-Modified颗粒度是秒,只能记录秒级的修改,比如1s内修改了N次,If-Modified-Since就无法判断了,所以要引入Etag。总结先执行强缓存策略,服务器通知浏览器一个缓存有效时间,在有效时间内,下次请求时直接使用缓存,不发起http请求,缓存从from memory cache或from disk cache中读取,若超过了有效时间,则执行协商缓存策略对于协商缓存,将缓存信息中的Etag和Last-Modified的值通过If-None-Match和If-Modified-Since发送给服务器,由服务器进行校验,若资源无更改,返回304,浏览器继续使用缓存,若资源被更改,则返回资源,状态码200,同时浏览器更新缓存流程图浏览器第一次请求:浏览器第二次请求:5. Http长连接keep-alive三个概念短连接所谓短连接,就是每次请求一个资源就建立连接,请求完成后立马关闭。每次请求都经过“创建TCP连接 -> 请求资源 -> 响应资源 -> 释放连接”。长连接所谓长连接(persistent connection),就是只建立一次TCP连接,多次HTTP请求都复用该连接。并行连接所谓并行连接(multiple connection),其实就是并发的短连接。keep-alive在HTTP/1.0里,为了实现client到web-server能支持长连接,必须在HTTP请求头里显式指定Connection: keep-alive在HTTP/1.1里,就默认开启了keep-alive,要关闭keep-alive必须在HTTP请求头里显式指定Connection: close现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。keepalive_timeoutHttpd守护进程,一般都提供了keep-alive timeout时间设置参数。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。这个keepalive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接。Nginx配置中的keepalive_timeout默认为75s,6. cookie与Session这个重点在于理解,这里就不赘述了。7. 网页经历了什么这个东西很多,后面会专门写一篇文章来进行说明。参考文章:HTTP1.0、HTTP1.1 和 HTTP2.0 的区别彻底弄懂HTTP缓存机制及原理What is the difference between memory cache and disk cache in Chrome?理解HTTP之keep-alive