当前位置: 首页 > Web前端 > JavaScript

http学习分享

时间:2023-03-26 23:12:12 JavaScript

http学习分享早在HTTP建立之初,主要目的是将超文本标记语言(HTML)文档从网络服务器传输到客户端的浏览器。http目前有http1.0:1996年首次用于网页http1.1:1999年才在主流浏览器中广泛使用http2:2015年正式发布http3:2018年提出http-over-quic更名为http3,并于2019年9月向Cloudflare和GoogleChrome(Canary构建)添加了HTTP/3支持。FirefoxNightly在Fall2019之后增加了支持。截至2021年6月,HTTP/3仍处于草案状态http1.0HTTP1.0规定浏览器和服务器只保持短期连接。打开TCP连接时,服务器不会跟踪每个客户端,也不会记录过去的请求。当浏览器发起多次请求时,性能问题更加明显,每次请求都需要重新建立连接,而HTTP1.1在1999年开始广泛应用于各大浏览器的网络请求,目前HTTP1.1是使用最广泛的HTTP协议。http1.1Http1.1针对http1.0优化缓存处理。在HTTP1.0中,Header中的If-Modified-Since和Expires主要作为缓存判断的标准。HTTP1.1引入了更多的缓存控制策略,如Entitytag、If-None-Match、cache-control和更多可选的缓存头来控制缓存策略。(可以打开这个链接查看请求头和响应头以及下面描述的对应关系:请求头和对应头的经验)If-Modified-Since:If-Modified-Since是一个标准的HTTP请求头标签。在发送HTTP请求时,将浏览器缓存的资源的最后修改时间一起发送给服务器,服务器会将这个时间与服务器上实际文件的最后修改时间进行比较。一致时间:HTTP状态码为304,取浏览器缓存的文件直接显示;时间不一致,http状态码200,浏览器再次缓存新文件;expires:资源过期的日期,过期时间还没过,直接拿浏览器缓存,不发http请求,时间过后直接读取服务器;实体标签:也叫Etag,由服务器生成,在对应的header中,当第二次请求时,请求头中会有If-None-Match,它的值就是Etag的值,如果一致与服务器上Etag的值,返回304,否则返回200和文件;(Etag和If-Modified-Since之间的区别?有时开发人员会在所有上传到服务器的文件重置所有文件的Last-Modified日期后修复某些内容,即使内容仅在一个子集上更改。为了适应这一点,大多数服务器还发送一个ETag。ETag代表EntityTag,是唯一的一个标识符,只会根据文件的内容而变化。大多数服务器实际上使用像SHA256这样的哈希函数来计算ETag。)缓存控制:这允许服务器控制客户端如何缓存收到的响应以及缓存多长时间,值包括:max-age(可以缓存多长时间,以秒为单位),public(可以被任何缓存区缓存),private(个人用户可以缓存,proxyserverscannotcache),no-cache(不会提示浏览器是否缓存内容,而是告诉浏览器使用其他验证方式,比如etag等)带宽优化和网络链接的使用:在http1.0,一个请求发送后,只有整个file可以返回,但是HTTP1.1在请求头中引入了range头字段,只允许请求资源的某一部分,即返回码为206(PartialContent)。一个ip可以托管上千个网站。当对这些网站的请求到来时,服务器根据Host行中的值来判断这个请求具体是哪个网站的长链接:在请求头中添加:Connection:keep-alive,一个TCP连接上可以发送多个连接.HTTP请求和响应,减少建立和关闭连接的消耗和延迟(为什么?因为之前的连接,请求完成后,连接并没有关闭,而是重新用于下一次请求)错误通知管理,在HTTP1.0中。1增加24个错误状态响应码,如409(Conflict)表示请求的资源与当前资源状态冲突;410(Gone)表示服务器上的资源被永久删除。chunk:当客户端向服务器请求静态页面或者图片时,服务器可以清楚的知道内容的大小,然后通过Content-Length消息头字段告诉客户端要接收多少数据。但是如果是动态页面等,服务器是不可能提前知道内容的大小的。这时候就可以使用Transfer-Encoding:chunk方式来传输数据。也就是说,如果要生成数据同时发送给客户端,服务端需要使用“Transfer-Encoding:chunked”,而不是Content-Length。Http1.1缺陷head-of-lineblocking:head-of-lineblocking是指当顺序发送的请求序列中的一个请求由于某种原因被阻塞时,后面排队的所有请求也被阻塞,这会导致客户端延迟数据没收到。(为什么?因为浏览器的最大并发连接数是有上限的,如果前面的请求没有响应,链接就会一直被占用,后面的请求就发不出去。)协议是针对连接状态没有记忆能力的。纯HTTP没有cookie之类的机制,每次连接都是一个新的连接。上一次请求验证了用户名和密码,下一次请求的服务器不知道它与上一次请求有什么关系,换句话说,登录状态被丢弃。(为什么是无状态的?因为是纯http请求,每次请求完成后,链接关闭,每个链接之间没有连接)不安全:传输内容没有加密,有可能被篡改和劫持中途。在https握手过程中,客户端首先通过URL访问服务器,建立SSL连接。服务器端收到客户端的请求后,会向客户端发送一份网站支持的证书信息(证书中包含公钥)。浏览器客户端根据双方约定的安全级别随机生成一个会话密钥,然后用服务器的公钥加密会话密钥发送给服务器。(非对称加密)服务器使用自己的私钥解密会话密钥。(对称加密)服务器使用会话密钥加密与客户端的通信。(对称加密)(对称加密和非对称加密需要展开的内容比较大,需要单独分享)http2http2和http1.1的区别:多路复用(MultiPlexing)首先区分请求和连接,连接是在客户端之间和服务器建立连接。连接成功后,就可以发送请求了。多路复用是连接共享。在http1.x中,一个链接只能发送一个请求。如果我们同时向同一台服务器发送多个请求,由于浏览器的最大连接数是有限的,所以对同一台服务器的请求需要排队,但是http2,对于同一个域名,只有一个链接,同一个连接内发起多个请求,没有请求次数限制。多路复用解决了浏览器限制同一域名下请求数的问题,也更容易实现全速传输。毕竟开启新的TCP连接需要慢慢提高传输速度。http2的体验如上图所示。多路复用技术可以只通过一个TCP连接传输所有的请求数据。新的二进制格式(BinaryFormat):tcp协议本身只考虑链路,不考虑传输的数据格式,也没有定义只能传输什么数据。http协议基于tcp协议。http协议定义协议只能传输文本HTTP1.x的解析是基于文本的。基于文本协议的格式分析存在天然缺陷,文本的表达形式多样。出于健壮性的考虑肯定有很多场景,但是二进制不一样,只识别0和1的组合。基于这种考虑,HTTP2.0的协议分析决定采用二进制格式,实现起来方便、健壮。接下来介绍几个重要的概念:stream:stream是连接中的虚拟通道,可以承载双向消息;每个流都有一个唯一的整数标识符(1,2...N);message:指逻辑HTTP消息,如请求、响应等,由一个或多个帧组成。Frame:HTTP2.0通信的最小单位。每个帧都包含一个帧头,至少标识当前帧所属的流,携带特定类型的数据,如HTTP头、负载等。在HTTP/2中,在同一个域名下所有的通信都是通过单个连接,可以承载任意数量的双向数据流。每个数据流都作为消息发送,消息又由一个或多个帧组成。多个帧可以乱序发送,可以根据帧头中的流标识重新组合。header压缩,上面说了,对于前面说的,HTTP1.x的header包含了很多信息,每次都要重复发送。HTTP2.0使用编码器来减小要传输的标头的大小。通信双方都缓存了一个header字段表,避免了重复的header。传输,这减少了所需传输的大小。HTTP/2使用客户端和服务器上的“头表”来跟踪和存储以前发送的键值对。对于相同的数据,不再通过每次请求和响应发送;header表在HTTP/2的连接期间一直存在,并由客户端和服务器端逐步更新;每个新的标题键值对要么附加到当前表的末尾,要么替换表中的先前值。比如下图中的两个请求,request的header字段都发送完后,第二个请求只需要发送difference数据即可,这样可以减少冗余数据,减少开销。缓存的内容是提前推送的,也叫“缓存推送”。可以想象,客户端肯定会请求一定的资源。这时候可以利用服务端推送技术,将需要的资源提前推送到客户端,这样可以相对减少延迟时间。当然,如果浏览器兼容,你也可以使用prefetch。比如服务端可以主动推送JS和CSS文件给客户端,而不是在客户端解析HTML的时候再发送这些请求。服务端可以主动推送,客户端也有选择是否接收的权利。如果服务器推送的资源已经被浏览器缓存,浏览器可以通过发送RST_STREAM帧来拒绝。主动推送也遵循同源策略。也就是说,服务端不能随便向客户端推送第三方资源,必须经过双方确认。http3小扩展HTTP/2虽然解决了之前版本的很多问题,但是它仍然存在一个巨大的问题,这主要是底层支持的TCP协议造成的。背景:如上所述,HTTP/2使用多路复用。一般来说,同一个域名下只需要使用一个TCP连接即可。但是当这个连接出现丢包的时候,整个TCP就会开始等待重传,这会导致后面所有的数据都被阻塞(为什么?),但是对于HTTP/1.1来说,可以开启多个TCP连接,这个这种情况只会影响其中一个连接,其余的TCP连接仍然可以正常传输数据,这会导致HTTP/2的性能比HTTP/1差。那么有人可能会考虑修改TCP协议。其实这已经是不可能完成的任务了。因为TCP存在时间太久,已经泛滥在各种设备中,而且这个协议是操作系统实现的,所以更新它也不现实。为此,Google开始创建基于UDP的QUIC协议,并将其用于HTTP/3。HTTP/3之前被命名为HTTP-over-QUIC。从这个名字我们也可以发现,HTTP/3最大的改造就是QUIC的使用。HTTP/2虽然支持多路复用,但是TCP协议毕竟没有这个功能。QUIC原生实现了这个功能,传输的单个数据流可以保证有序传递,不影响其他数据流。该技术解决了之前TCP存在的问题。与HTTP2.0一样,可以在同一个QUIC连接上创建多个流来发送多个HTTP请求。但是QUIC是基于UDP的,一个连接上的多个流之间没有依赖关系。比如stream2丢了一个UDP包,不会影响后面的Stream3和Stream4,也不存在TCP的队头阻塞。虽然stream2的包需要重传,但是stream3和stream4的包不需要等待就可以发送给用户。