一.一个完整的 HTTP 连接
一个完整的 http 连接有五个步骤;
1.TCP 三次握手
该部分表示 A 向 B 发出请求,建立连接
(一)第一次握手(A->B):
A 向 B 发送一个 TCP 的包,带上了标志 SYN
,表示要建立一个连接,并指明包开始的序列号 seq,以后传送的字节编号都是以这个作为起点,并告知能接收的最大报文段长度 mms 为 1460,一般 mms 都是1460.
(二)第二次握手(B->A):
B 进行回复,发送一个 SYN + ACK 的报文段,表示同意建立连接
(三)第三次握手(A->B)
A 收到 SYN 之后,向 B 发送一个 ACK,完成三次握手。
为什么 TCP 握手要三次?
TCP 前两次的握手就可以确定对方的存在,第三次的握手是为了防止已失效的连接请求报文段突然又传送到B,因而产生错误。 异常情况:假设 A 向 B 发送了一个连接请求报文段,但是因为某些网络结点长时间滞留,以致延迟到连接请求释放后的某个时间才到达 B。本来这是一个早已失效的请求报文段,但 B 收到此失效请求报文段后,就误认为 A 又发出一次新的连接请求。于是就想 A 发出确认报文段。若,只有两次握手,B 就是一只建立连接,浪费资源。但如果有 第三次握手,B 一直都没有接收到 A 发回来的第三次确认,就会自动断开连接。
2.接收窗口
(一) TCP 的流量控制
通过滑动窗口机制进行流量控制
(二) TCP 的拥塞控制
- 慢开始和拥塞避免
- 快速重传和快恢复算法
此处简写接收窗口的控制机制
3.发送数据
此部分省略吧~
4.关闭连接 四次挥手
(一)第一次挥手
当 A 觉得不用再请求数据时,等过了 30S 就要把请求链接关闭,向 B 发送一个 FIN 的报文。
为什么需要等 30s 才关闭呢?
因为 HTTP 1.1 版本之后的请求的 Connection:keep-alive 字段的影响。因为同一个域可能要请求多个资源,如果每请求一次就关闭连接。下次请求时,又要建立 TCP 连接,是浪费资源的。
(二)第二次挥手
B 收到 A 发来的包后,向 A 发送一个 ACK ,这时连接处于半关闭状态,A 不能向 B 传送数据,但是 B 可以向 A 发送数据。
(三)第三次挥手
当 B 觉得没有数据需要传送时,向 A 发送 FIN
(四)第四次挥手
A 收到 B 发来的结束连接请求,向 B 发送一个 ACK ,此时连接完全关闭。然后主动关闭方 A 进入 TIME_WAIT (时间等待)状态。
5.TIME_WAIT
TIME_WAIT 时间为 2MSL(maximum segmentt live-time),标准建议为 2 分钟,但是实际运用中,2 分钟太长了。
为什么 A 在 TIME_WAIT 状态下必须等待 2MSL ?
原因有二,一是:为了保证 A 最后发送的 ACK 能够成功到达 B 端。二是:防止上一节“三次握手”处提及到的“已失效的连接请求报文段”出现在本链接中。A 在发送完最后一个 ACK 报文段后,再经过 时间 2MSL 后,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。
http/https 协议
1.http协议格式
- request: request-line(由三部分组成 1.请求方法;2.请求地址;3.请求协议和版本) head body
- response response-line(由三部分组成 1.协议和版本,状态码,状态文本) head body
2.http状态码和状态文本
- 1XX 临时回应,表示客户端请继续
- 2XX
-
- 200 请求成功
- 3XX 表示请求的目标有变化,希望客户端进一步处理
-
- 301&302 永久性和临时性跳转
-
- 304 客户端缓存没有跟新
- 4XX
-
- 403 没有权限
-
- 404 页面不存在
-
- 418 it‘s a teapot
- 5XX 服务端错误
-
- 500 服务器错误
-
- 503 服务器端暂时性错误,可以一会再试
3.http request Head 请求头
- accept 浏览器端接受的格式
- accept-encodind 浏览器端接受的编码格式
- accept-language 浏览器端接受的语言
- cache-control 控制缓存的时效性
- connection 连接方式 如果是 keep-alive 且浏览器支持,会用复用连接
- host http访问使用的域名
- if-modified-since 上次访问时的更改时间,如果服务器端认为此后没有更新,则会返回304
- if-none-match 上次访问的etag,通常是页面的信息摘要
- user-agent 客户端表示
- cookie 客户端缓存的饿cookie 字符串
4.http response head 响应头
- cache-control 缓存控制 用于通知各级缓存保存的时间
- connection 连接方式
- content-encoding 内容编码 通常是 gzip
- content-length 内容长度 ,浏览器用于判断内容是否已经结束
- content-type 内容类型,所有请求网页的都是 text/html
- date 当前服务器时间
- eatg 页面的信息摘要,用于判断是否需要重新到服务器取回页面
- expires 过期时间,用于判断下次请求是否要到服务器端取回页面
- keep-alive 保持连接不断时需要的一些信息,如 timeout,max
- last-modifiled 上次修改时间
- server 服务器软件类型
- set-cookie 设置cookie
- via 服务端的请求链路
5.http request body 响应体
- application/json
- application/x-www-form-ulencoded
- multipart/form-data
- text/html
6.https
https 有两个作用:
- 一是用于确定请求的目标服务器的身份;
- 二是保证传输的数据不会被网络中间窃听或者篡改,即是防止中间人攻击。
(一)中间人攻击方式
1.域名污染
由于我们访问一个域名时需要先进行域名解析(在没有缓存的情况下),即向 DNS 服务请求某个域名的 IP 地址。在经过 DNS 的中间链点可能会被抢答,返回一个错误的 IP 地址,这个 IP 地址有可能就指向中间人的机器。
2.APR 欺骗
广域网的传输用的是 IP 地址,而在局域网里面是用物理地址,例如路由器需要知道连接它的设备的物理地址才能发送数据包,当路由器不知道对应的物理地址时,会通过 ARP 广播,向所有设备查询某个 IP 地址对应的物理地址。由于这个局域网内的所有机器都会受到这个包,所以这时候就可以欺骗路由器。
安全
xss (cross site scripting)
是一种网站应用程序的安全漏洞,它允许恶意者将代码注入到网页上。通过修改 html 结点或者执行 js 代码来攻击网站
防御:
- 转义输入输出的内容,设置白名单
- CSP content-security-policy,通过在 http header 中开启 CSP。本质上,也是设置白名单,通过规范浏览器只能够执行特定来源的代码
只允许加载本站资源 Content-Security-Policy: default-src ‘self’
只允许加载 HTTPS 协议图片Content-Security-Policy: img-src https://*
允许加载任何来源框架Content-Security-Policy: child-src 'none'
- cookie 设置 httpOnly
CSRF (cross site request forgery)
简单地说,就是利用用户的登录态发起恶意请求
防御
- get 请求不对数据进行修改
- 不让第三方网站访问到 cookie
可以对 Cookie 设置 sameSite ,该属性设置 Cookie 不随着跨域请求发送。
- 阻止第三方网站请求
通过验证 referer 来判断请求是否为第三方网站发起
- 请求时,附带验证信息,如验证码或者 token
服务器下发一个随机的 token,每次请求都将 token 带上,服务器判断 token 是否有效。
(未完待续 ...)
欢迎大家在评论区共同探讨 ~
希望写的文章能够为同在坑里的你我解答一点点的疑问~
参考文献
- 《计算机网络》(第七版)谢希仁著
- 《高效前端》李银城著