原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】说到http协议,大家的第一印象会直接想到tcp-ip+ssl/tls的握手过程。今天从另一个角度梳理一下http相关的一些知识点。这篇文章主要有7个方面,即1.http的演变史。会简要介绍每个版本的更新内容,遇到的问题以及当时的改进计划。2.HTTP缓存策略3.跨域策略4.HTTP并发问题5.get/post与普通端口号的区别。6.一些开放性问题。7.最后,列出写这篇文章的过程中参考的巨人肩膀。一、HTTP的演变1、HTTP0.9只允许客户端发送GET请求,不支持请求头。只支持一种类型的内容,即纯文本。支持HTML,但无法插入图片。2.HTTP1.0请求和响应支持标头域响应对象以响应状态行开头。响应对象不限于超文本。支持客户端通过POST方式向web服务器提交数据,支持GET、HEAD、POST方式,支持长连接(但默认使用短连接),缓存机制,以及身份认证3、新特性http1.1:默认为持久连接HTTP1.1支持持久连接(PersistentConnection)和请求流水线(Pipelining)处理,多个HTTP请求和响应可以在一个TCP连接上传输,减少了建立和关闭连接的消耗和延迟,Connection:keep-alive在HTTP1.1中默认是开启的,一定程度上弥补了HTTP1.0每次请求都创建一个连接的缺点。提供范围请求功能(宽带优化)。在HTTP1.0中,存在一些浪费带宽的现象。比如客户端只需要一个对象的一部分,而服务端发送的是整个对象,并且不支持续传功能,HTTP1.1在请求头中引入了range头域,只允许某一部分请求资源的编号,即返回码为206(PartialContent),方便开发者自由选择,充分利用带宽和连接数。这是支持文件恢复的基础。HTTP1.0中提供虚拟主机(HOST域)的功能考虑到每个服务器都绑定了一个唯一的IP地址,因此,请求报文中的URL不传递主机名(hostname)。但是随着虚拟主机技术的发展,一台物理服务器上可以存在多个虚拟主机(Multi-homedWebServers),它们共享一个IP地址。HTTP1.1的请求报文和响应报文都应该支持Host头域,如果请求报文中没有Host头域,就会报错(400BadRequest)。更多缓存处理领域HTTP/1.1在1.0的基础上增加了一些新的缓存特性,引入了实体标签,一般称为e-tags,并增加了更强大的Cache-Control头。错误通知的管理在HTTP1.1中增加了24个错误状态响应码。例如409(Conflict)表示请求的资源与资源当前状态冲突;410(Gone)表示服务器上的资源已被永久删除。删除。问题:高延迟——线头阻塞(Head-Of-LineBlocking)无状态特性——阻碍了交互协议对连接状态没有记忆能力,服务器不知道它与之前的请求有什么关系,在也就是说,失去登录状态明文传输——不安全的传输内容没有加密,中间可能被篡改劫持。改进方案:针对队头拦截:1、将同一页面的资源分散到不同域名下,增加连接数限制。虽然可以共享一个TCP管道,但是在一个管道中一次只能处理一个请求,其他请求只能阻塞到当前请求结束。2.减少请求数3.内联一些资源:css,base64图片等4.合并小文件减少资源数不安全:1.https2.token验证3.自定义/协议:数据加密方案4,http2新特性:二进制帧传输:1)HTTP2.0的所有帧都是用二进制编码的2)帧是最小的数据单元,每个帧都会标识该帧属于哪个流,stream是由多个帧组成的数据流动。多路复用意味着多个流可以存在于一个TCP连接中。3)帧:客户端和服务器通过交换帧进行通信,帧是基于这种新协议的最小通信单位。4)消息:指逻辑HTTP消息,如请求、响应等,由一个或多个帧组成。5)流:流是连接中的虚拟通道,可以承载双向消息;每个流都有一个唯一的整数标识符(1、2...N);多路复用-解决线头阻塞多路复用用于允许通过单个HTTP/2.0连接同时发送多个请求-响应消息。有了新的分帧机制,HTTP/2.0不再依赖多个TCP连接来处理更多的并发请求。每个数据流被分成许多独立的帧,这些帧可以交错(乱序发送),并且可以区分优先级。最后根据每个帧头的流标识在另一端重新组装。HTTP2.0连接是持久的,客户端和服务器之间只需要一个连接(每个域名一个连接)。HeaderCompression——解决庞大的HTTPHeadersHTTP/1.1的header携带了很多信息,每次都要重复发送。HTTP/2.0要求通信双方都缓存一个头字段表,从而避免重复传输。请求优先级——优先获取重要数据浏览器可以在找到资源时立即调度请求,指定每个流的优先级,让服务器决定最佳响应顺序。这样,请求就不用排队了,既节省了时间,又最大限度地利用了每个连接。服务端推送——补缺,提高请求效率。请求index.html可以直接返回第一次依赖的js和css。方法是在nginx上配置,提高安全性。HTTPS-basedproblem:TCPandTCP+TLSconnectionestablisheddelay:TCP连接需要与服务器进行三次握手,消耗1.5RTT(Round-TripTime,往返延迟),丢失的数据包必须等待重传确认。当HTTP2丢包时,整个TCP都要等待重传,那么TCP连接中的所有请求都会被阻塞。多路复用导致服务器压力上升多路复用很容易Timeout5,http3[Google基于UDP的QUIC协议]新特性:改进拥塞控制,可靠传输和快速握手集成TLS1.3加密多路复用连接迁移问题:NAT在一些NAT网络环境中(比如如某些校园网),UDP协议会被路由器等中间网络设备禁止。此时客户端会直接降级,选择HTTPS等替代通道,保证业务请求的正常进行。二、缓存1、缓存类型200formmemorycache:在不访问服务器的情况下,一般资源已经加载缓存在内存中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放),再次打开同一个页面时,frommemorycache也不会出现。200fromdiskcache:没有访问服务器,之前某个时间加载过资源,直接从硬盘读取缓存。关闭浏览器后,数据依然存在,关闭页面时不会释放资源,下次打开时仍会从磁盘缓存中获取。先访问内存缓存,再访问磁盘缓存,最后请求网络资源在设定的时间内直接读取缓存,不再请求Cache-Control:当该值设置为max-age=300时,表示资源是请求正确返回时间后5分钟内再次加载(浏览器也会记录),会命中强缓存。privateNone表示响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存)public可以省略,表示响应可以被任何对象缓存(包括:发送请求的客户端、代理服务器等)no-cache可以省略,缓存前必须确认其有效性no-store不缓存请求或响应的任何内容max-age=[s]最大值所需响应的(1)max-age:用于设置资源(representations)可以被缓存多长时间,以秒为单位;(2)s-maxage:与max-age相同,但仅用于代理服务器缓存;(3)public:可以省略,表示响应可以被任何缓存缓存;response可以被任何对象缓存(包括:发送请求的客户端、代理服务器等)(4)private:没有参数,只对个人用户有效,不能被代理服务器缓存;(5)no-cache:可以省略强制客户端直接向服务器发送请求,也就是说每次请求都必须发送到服务器。服务器收到请求,然后判断资源是否发生变化,如果是则返回新的内容,否则返回304,不变。这很容易产生误解,让人误以为没有缓存响应。实际上,Cache-Control:no-cache会被缓存,但是每次向客户端(浏览器)提供响应数据时,缓存都必须评估缓存的响应对服务器的有效性。(6)no-store:无参数,禁止所有缓存(这是响应不缓存的意思)。2)协商缓存last-modify+if-modify-sincehttp1.0Last-Modified:浏览器向服务器发送资源的最后修改时间If-Modified-Since:资源过期时(浏览器判断max-ageexpired),如果发现响应头有Last-Modified语句,那么会再次向服务器添加headerif-modified-since来表示请求时间。服务器收到请求后,找到if-modified-since,与请求资源的最后修改时间(Last-Modified)进行比较。如果上次修改时间较新(较大),说明该资源又被修改过,返回最新的资源。HTTP200正常;如果上次修改时间更旧(更小),说明该资源没有新的修改,响应HTTP304,去缓存。ETag+if-not-matchHTTP1.1Etag是HTTP1.1的一个属性,由服务端(Apache或其他工具)生成返回给前端,帮助服务端控制Web端的缓存校验。在Apache中,ETag的值默认是通过对文件的索引节点(INode)、大小(Size)和最后修改时间(MTime)进行哈希处理得到的。if-not-match当资源过期,浏览器发现响应头中有Etag时,会再次将请求头if-none-match(值为Etag的值)带回服务器。服务端收到请求对比,决定返回200或3043)不缓存Pragma:no-cache/catch-control:no-store4)如果缓存优先顺序为判断http1.0[Pragma:no-cache],然后是Cache-Control,然后是Expires,然后是[ETag,最后是Last-Modified,全部满足则为304,有一项不满足则为200。】strongcacheexpires更多的是支持http/1.0的古浏览器的响应头,是特定的时间点。客户端和服务端的时间可能不一致,也可能因为网络延迟导致时间不准确。cache-control:max-age是秒数,两者同时出现。以最大年龄为准。协商缓存在一般的分布式环境(如CDN)中,很少使用ETag,因为ETag依赖于WebServer的哈希算法,不同的WebServer,不同的版本,不同的配置,会导致同一个文件ETag可能不一样等于。当然,如果能限制以上信息相同,也可以用ETag,不绝对。Last-Modified时间精度是几秒钟的事情。如果在1s内被修改,Last-Modified不会改变。eTag采用摘要算法,可以及时刷新。3.不同行为导致的缓存在URI输入框输入回车通过书签访问浏览器发现资源已经被缓存且没有过期(通过Expires头或者Cache-Control头),并没有不与服务器确认,直接使用浏览器缓存的内容。响应内容与之前的响应内容完全一致,比如Date时间就是上次响应的时间。所以我们也可以看到资源大小来自cacheF5/点击工具栏刷新按钮/右键菜单重新加载F5,浏览器无论如何都会向服务器发送一个HTTPRequest,即使有Expires前面响应中的headerCtl+F5Ctrl+F5想要的是完全从服务器获取一个新的资源,所以不仅需要向服务器发送HTTP请求,而且没有If-Modified-Since/If-这个请求中的None-Match,这样就强制服务器不返回304,而是原样返回整个资源,这样Ctrl+F5造成的传输时间就变长了,自然网页的刷新也是慢点。我们可以看到该操作返回了200并刷新了关联的缓存控制时间。为了保证你得到的是服务器最新的,Ctrl+F5不仅去掉了If-Modified-Since/If-None-Match,还需要添加一些HTTPHeaders。根据HTTP/1.1协议,Cache不仅存在于Browser端,Browser和Server之间的中间节点(如Proxy)也可能起到Cache的作用。为了防止只获取到这些中间节点的Cache,需要告诉他们不要使用我自己的Cache,对我敷衍了事,所以向upstream节点索要最新的copy。在Chrome51中,会包含两个header信息,作用是让本次请求的中间Cache失效,让返回的资源绝对新鲜。Cache-Control:no-cachePragma:no-cache3.跨域问题1.协议原理|站点域名|localStorage的数据不能共享。3、解决方案1)jsonP,JSONP只支持GET请求。优点是支持老浏览器,可以向不支持CORS的网站请求数据。2)Cros,CORS支持所有类型的HTTP请求3)iFrame嵌套4)postMessage:postMessage(data,origin)方法允许来自不同源的脚本以异步方式通信,实现跨文本文档、多窗口、和cross-domainMessaging*safari,父页面无法向iframe中的跨域页面传递信息,使用url传值的方式实现跨域存储功能,可以使用页面url参数(safari浏览器可以支持超过64k字符的长度)5)新的跨域策略:跨域隔离COOP,COEP4.并发问题1.现代浏览器与服务器建立TCP连接后,HTTP后会断开吗请求完成了吗?什么情况下会掉线?在HTTP/1.0中,服务器发送HTTP响应后,会断开TCP连接。虽然没有在标准中设置,但有些服务器支持Connection:keep-alive标头。HTTP/1.1将Connection头写入标准,默认启用持久连接。除非请求指定Connection:close,否则浏览器与服务器之间的TCP连接会保持一段时间。2.一个TCP连接可以发送多个HTTP请求。3、HTTP请求能否在一个TCP连接中一起发送(比如3个请求一起发送,3个响应一起接收)?HTTP/1.1中存在问题。单个TCP连接一次只能处理一个请求,任何两个HTTP请求从开始到结束的时间不能在同一个TCP连接中重叠。HTTP/1.1规范规定Pipelining,一种支持持久连接的客户端,可以在一个连接中发送多个请求(无需等待任何请求的响应)。接收请求的服务器必须按照收到请求的顺序发送响应。但是这个特性在浏览器中默认是关闭的。由于HTTP/1.1是文本协议,返回的内容无法区分发送的是哪个请求,所以顺序必须保持一致。默认情况下,现代浏览器不启用HTTP管道。某些代理服务器无法正确处理HTTPPipelining。正确的流水线实现很复杂。Head-of-lineBlockingconnection头阻塞优化维护与服务器建立的TCP连接,在同一个连接上顺序处理多个请求。与服务器建立多个TCP连接。HTTP2提供了Multiplexing特性,可以在一个TCP连接中同时完成多个HTTP请求。4、为什么有时刷新页面后没有重新建立SSL连接?TCP连接有时会由浏览器和服务器维护一段时间。TCP不需要重新建立,SSL自然会用上一个。5、浏览器是否限制同一主机的TCP连接数?Chrome允许最多六个TCP连接到同一主机。如果图片都是HTTPS连接,并且在同一个域名下,浏览器会在SSL握手后与服务器讨论是否可以使用HTTP2。如果是这样,请在此连接上使用多路复用功能。不要使用HTTP2或https进行多路复用。浏览器会在一个HOST上建立多个TCP连接。最大连接数取决于浏览器设置。这些连接将被浏览器用来在空闲时发送新的请求。如果所有连接都在发送请求?所有其他请求都必须等待。五、请求相关1、获取post差异*Get方法的含义是向服务器请求获取资源。这个资源可以是静态的文本、页面、图片和视频等。*Post向URI指定的资源提交数据,数据放在消息体中。*GET方法是安全和幂等的,POST不是*安全和幂等的概念:*在HTTP协议中,所谓“安全”是指请求方法不会“破坏”服务器上的资源。*所谓“幂等”,就是同一个操作多次执行,结果“相同”。2、常用的端口号200“204NoContent”也是一种常见的成功状态码,与200OK基本相同,只是响应头没有body数据。“206PartialContent”应用于HTTP分块下载或断点续传,表示响应返回的body数据不是资源的全部,而是资源的一部分,也是服务器处理成功的状态。300301MovedPermanently”表示永久重定向,表示请求的资源已经不存在,需要用新的URL重新访问。302Found”表示临时重定向,表示请求的资源还在,只是暂时需要另外一个URL访问。301和302都会使用响应头中的字段Location来表示后面要重定向的URL,并且浏览器会自动重定向到新的URL。“304NotModified”没有跳转的意思,表示资源没有被修改,重定向已有的缓冲文件,也称为缓存重定向,用于缓存控制.400“403Forbidden”表示服务器禁止访问资源,并不是客户端的请求有误。500500InternalServerError”和400类型是general和general的错误码,我们不知道服务器发生了什么错误。“501NotImplemented”表示客户端请求的功能还不支持,类似于“openingsoon”,敬请期待。“502BadGateway”通常是服务器作为网关或代理返回的错误码,表示服务器本身工作正常,访问后端服务器时出现错误。”503ServiceUnavailable”表示服务器当前正忙,暂时无法响应服务器,类似于“网络服务繁忙,请稍后再试”。6、边界问题*A、B机器正常连接后,B机器突然重启。问A此时TCP处于什么状态*[https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/21](https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/21)*一个TCP连接可以发送多少个HTTP请求*[https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1](https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1)7.参考链接*【【手动精修】硬核!30道图解HTTP常见面试题](https://www.cnblogs.com/xiaolincoding/p/12442435.html)*【HTTP的发展与演进】(https://www.cnblogs.com/xiaolincoding/p/12442435.html)*[一个TCP连接可以发送多少个HTTP请求](https://maimai.cn/article/detail?fid=1565594485&efid=2XGge6_3eNs_d2tiQsBWRw&use_rn=1)*[浏览器HTTP缓存机制](https://juejin.cn/post/6844903554587574285)*【强制缓存与协商缓存】(https://juejin.cn/post/6844903838768431118)*【缓存优先级】(https://segmentfault.com/q/1010000022541364)*【http区别](https://zhuanlan.zhihu.com/p/102561034)*[HTTP0.9HTTP1.0HTTP1.1与HTTP2.0的区别](https://www.cnblogs.com/wupeixuan/p/8642100.html)*[HTTP缓存控制总结](https://imweb.io/topic/5795dcb6fb312541492eda8c)不是容易原创,如需转载请【联系作者】或【署名作者并注明文章出处】
