有些同学可能不理解,为什么前端同学还要学习和了解 http 的相关知识?其实很多内容在我们的开发过程中都是有用到的,了解更多 http 相关的知识,更能方便我们定位问题,和优化性能。 最开始的时候客户端和服务器都是处于 CLOSED 关闭状态。主动打开连接的为客户端,被动打开连接的是服务器。 TCP 服务器进程先创建传输控制块 TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了 LISTEN 监听状态 第一次握手 TCP 客户进程也是先创建传输控制块 TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位 SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP 客户端进程进入了 SYN-SENT 同步已发送状态 第二次握手 TCP 服务器收到请求报文后,如果同意连接,则会向客户端发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是 ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP 服务器进程进入了 SYN-RCVD 同步收到状态 第三次握手 TCP 客户端收到确认后,还要向服务器给出确认。确认报文的 ACK=1,ack=y+1,自己的序列号 seq=x+1,此时,TCP 连接建立,客户端进入 ESTABLISHED 已建立连接状态 触发三次握手 主要原因:防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误 第一次握手: 客户端向服务器端发送报文 如果采用两次握手会出现以下情况: 如果采用三次握手的话,就算那条失效的报文发送到服务器端,服务器端确认并向客户端发送报文,但此时客户端不会发出确认,由于客户端没有确认,由于服务器端没有接收到确认,就会知道客户端没有请求连接。 数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于 ESTABLISHED 状态,然后客户端主动关闭,服务器被动关闭。 第一次挥手 客户端发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为 seq=u(等于前面已经传送过来的数据的最后一个字节的序号加 1),此时,客户端进入 FIN-WAIT-1(终止等待 1)状态 第二次挥手 服务器端接收到连接释放报文后,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号 seq=v,此时,服务端就进入了 CLOSE-WAIT 关闭等待状态 第三次挥手 客户端接收到服务器端的确认请求后,客户端就会进入 FIN-WAIT-2(终止等待 2)状态,等待服务器发送连接释放报文,服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,服务器就进入了 LAST-ACK(最后确认)状态,等待客户端的确认。 第四次挥手 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是 seq=u+1,此时,客户端就进入了 TIME-WAIT(时间等待)状态,但此时 TCP 连接还未终止,必须要经过 2MSL 后(最长报文寿命),当客户端撤销相应的 TCB 后,客户端才会进入 CLOSED 关闭状态,服务器端接收到确认报文后,会立即进入 CLOSED 关闭状态,到这里 TCP 连接就断开了,四次挥手完成。 TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。TCP 是面向面向字节流,虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序看成是一连串的无结构的字节流。TCP 有一个缓冲,当应用程序传送的数据块太长,TCP 就可以把它划分短一些再传送。 TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等众多功能。 UDP 是面向报文的,所谓面向报文,是指面向报文的传输方式是应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则 IP 层需要分片,降低效率。若太短,会是 IP 太小。 UDP 是不具有可靠性的数据报协议,细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。 [特点] [不足] HTTP/1.0 版的主要缺点是,每个 TCP 连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。TCP 连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。所以,HTTP 1.0 版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。 [特点] [不足] 虽然 1.1 版允许复用 TCP 连接,但是同一个 TCP 连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。为了避免这个问题,只有两种方法:一是减少请求数,二是同时多开持久连接。这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入 CSS 代码、域名分片(domain sharding)等等。如果 HTTP 协议设计得更好一些,这些额外的工作是可以避免的。 简单来说,HTTP/2(超文本传输协议第 2 版,最初命名为 HTTP2.0),是 HTTP 协议的第二个主要版本。HTTP/2 是 HTTP 协议自 1999 年 HTTP1.1 发布后的首个更新,主要基于 SPDY 协议。 HTTP2.0 的特点是:在不改动 HTTP 语义、方法、状态码、URI 及首部字段的情况下,大幅度提高了 web 性能。 HTTP2 协议虽然大幅提升了 HTTP/1.1 的性能,然而,基于 TCP 实现的 HTTP2 遗留下 3 个问题: HTTP3 协议解决了这些问题: 参考: https://zhuanlan.zhihu.com/p/431672713 。 将 html 解析成一个 DOM 树(深度遍历),将 css 解析成 css 规则树,浏览器引擎会将它们合并成渲染树。布局。绘制。 过程中,遇到 css,不会阻塞 DOM 树的解析,但会阻塞 DOM 树的渲染,并会阻塞 js 执行。 遇到 js,会阻塞 DOM 树的解析,所以 js 要放在下面或者异步加载。defer 或 async。 参考: https://www.xiabingbao.com/browser/2015/05/16/happens-type-in-url-browser.html。 通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP 缓存,变得更加响应性。 通常 http 缓存分为强缓存和协商缓存。 在浏览器加载资源时,先看看 cache-control 里的 max-age(或 expired 属性),判断数据有没有过期,如果没有直接使用该缓存,不再发送网络请求。 当 max-age 和 expired 同时存在时,max-age 优先级更高。 根据内容最后的修改时间(Last-Modified),或者标识(ETag),来判断内容是否发生了变化,若没有变化,则告诉浏览器直接使用缓存即可,否则返回最新的内容。 协商缓存是每次都要请求服务器的,然后服务器校验是走缓存,还是下发新的内容。当可以使用客户端的缓存时,只需要返回 304 状态码即可。 参考:https://www.xiabingbao.com/post/http/http-cache-rblrrn.html。 协议、域名、端口,任意一个不相同时,则会产生跨域。即 为了安全考虑,阻止恶意的攻击,减少可能被攻击的媒介。不遵循同源规则的,不允许访问。 因为跨域限制,是浏览器进行限制的。因此后端对后端的互相请求,即使协议、域名、端口等都不一样,也是没有所谓的跨域问题的。 前端依然会发出请求,后端接口会收到请求,并正常返回,但浏览器并不会处理。然后提示存在跨域错误。 跨源资源共享标准新增了一组 HTTP 标头字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。 当把 某些请求不会触发 CORS 预检请求,这样的请求一般称为 “简单请求” ,而会触发预检的请求则是 “复杂请求” 。 options 请求就是预检请求,可用于检测服务器允许的 http 方法。当发起跨域请求时,由于安全原因,触发一定条件时浏览器会在正式请求之前自动先发起 OPTIONS 请求,即 CORS 预检请求,服务器若接受该跨域请求,浏览器才继续发起正式请求;不支持的话,会在控制台显示错误 所以,当触发预检时,跨域请求便会发送 2 次请求。 永久重定向,请求的网页已永久移动到新位置,浏览器会自动重定向到新的 url 地址。而永久重定向的连接,浏览器本地是会有缓存的,下次再遇到相同的地址时,不再请求服务器,而是直接重定向。如 http 永久重定向到 https,旧地址永久重定向到新地址。 永久重定向的状态码有 301 和 308: 临时重定向,表示目标资源临时移动到了另一个 URI 上。因为是临时重定向,浏览器再次遇到之前的请求时,还是会重新请求服务器,再决定接下来的响应。如链接跳转经常使用这种方式,既能避免任意的外链跳转,也能统计链接的点击量。 临时重定向的状态码有 302, 303 和 307: GET 和 POST 是 HTTP 中最常用的两个方法。TCP 的三次握手与四次挥手 #
三次握手 #
证明客户端的发送能力正常
第二次握手:服务器端接收到报文并向客户端发送报文
证明服务器端的接收能力、发送能力正常
第三次握手:客户端向服务器发送报文
证明客户端的接收能力正常
客户端向服务器端发送的请求报文由于网络等原因滞留,未能发送到服务器端,此时连接请求报文失效,客户端会再次向服务器端发送请求报文,之后与服务器端建立连接,当连接释放后,由于网络通畅了,第一次客户端发送的请求报文又突然到达了服务器端,这条请求报文本该失效了,但此时服务器端误认为客户端又发送了一次连接请求,两次握手建立好连接,此时客户端忽略服务器端发来的确认,也不发送数据,造成不必要的错误和网络资源的浪费。四次挥手 #
tcp 和 udp 的区别,及使用场景? #
tcp #
UDP #
tcp 如何保证可靠传输? #
http 各个版本之间的区别? #
HTTP/1.0 #
HTTP/1.1 #
HTTP/2.0 #
HTTP/3.0 #
https 的连接和传输过程 #
DNS 的查找过程 #
URL 从输入到网页显示的全过程 #
强缓存和协商缓存 #
强缓存 #
协商缓存 #
为什么会有跨域?怎么解决? #
跨域的产生 #
同源安全策略
。跨域时,后端会收到请求吗? #
跨域的解决方案有哪些? #
access-control-allow-origin #
Access-Control-Allow-Origin
设置为*
时,即Access-Control-Allow-Origin: *
,则表示该资源可以被任意外源访问。但如果需要传递 cookie 时,请不要把下面的几个属性设置为*
,否则请求将会失败:
Access-Control-Allow-Origin: https://example.com
;注意,这里要把协议、域名和端口都要写完整,否则跟前端不一样的话,还是会跨域;Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
;Access-Control-Allow-Methods: POST, GET
;什么是简单请求和复杂请求,为什么会有 options 类型的请求? #
简单请求 #
复杂请求 #
options 请求 #
永久重定向和临时重定向? #
永久重定向 #
临时重定向 #
GET 请求和 POST 请求的区别 #
版权属于:
加速器之家
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
评论