HTTP/HTTPS

4 阅读10分钟

网络模型:

由上到下依次是

  1. 应用层: 数据 HTTP,DNS, 直接与用户交互
  2. 表现层: OSI7层模型中的, 数据格式转换,加密解密等,如SSL/TLS加密
  3. 会话层: OSI7层模型中的,管理不同应用进程的会话,包括建立,维持和终止连接以及会话同步和断点续传
  4. 运输层: 段(TCP)/数据报(UDP) TCP/UDP, 端到端的数据传输,进行流量控制和差错校验
  5. 网络层: IP/ARP/ICMP(注意ICMP包不关心大小,并且依赖IP,实际上是IP包的一部分,即ICMP把数据包装成ICMP包然后再由IP协议加上头部什么的包装成IP包), 数据包的路由选择和转发,通过IP地址实现跨网络通信,ARP实际在链路层,但常与网络层关联
  6. 数据链路层: MAC, 在相邻节点间传输数据帧,进行MAC寻址差错检测和流量控制
  7. 物理层: 比特流 定义物理介质的电气特性,信号编码等

HTTP vs HTTPS

HTTP与HTTPs的区别是SSL协议,HTTPs协议是安全协议,是运输层和应用层之间加了一层SSL协议(现在基本上已经被替换为TLS了)

  1. HTTP是未经安全加密的协议,传输过程中容易被攻击者监听,数据窃取
  2. HTTP的默认端口是80,HTTPS的默认端口是443

HTTP:

  1. get方法不安全,因为发送请求的时候请求参数会拼接在URL后面,容易被窃取,post请求请求体用户不会再地址栏直接看见,但是根据HTTP规范Post不安全get安全因为get不修改数据

  2. get请求的URL有长度限制,不同服务器,浏览器有不同标准

  3. get请求会被浏览器主动缓存,post不会

  4. get请求会发送一个TCP数据包,把httpheader和data一起发送过去(请求头大小小于一个TCP的最大字节数的情况,否则会分报但是仍然是一次HTTP请求),post一般也是发一个HTTP请求,但是如果设置Expect: 100 continue是会发送两个请求,先发送header,服务器响应100 continue,然后浏览器再发送data,一般是在要发送很大的数据包的时候

  5. 无状态协议指浏览器无法记忆事务处理状态,比如登录之后关闭浏览器再进就需要重新登录,现在大部分网站用Cookie解决问题,Cookie存在客户端,当进入某个网站的时候浏览器会自动去找客户端存的是否有这个网站的Cookie,有的话发给服务端,服务端进行校验,如果Cookie正确且每过期就自动登录,注意Cookie会绑定一个域名属性,所以受同源策略影响

    还有JWT也是用来做这个的,JWT是本地校验的,JWT跟同源策略完全无关,JWT本质上就是一串普通字符串,他所有的特殊行为都是使用它的开发者自己定义的

  6. TCP vs UDP:

    1. UDP是尽最大可能交付,是不可靠的交付,不需要握手操作,因此速度很快延迟低,但是UDP发送数据包不会等待确认,只管发送,所以UDP发送的数据包有可能丢包,允许DNS查找,DNS是建立在UDP上的协议

    2. TCP需要先通过三次握手建立连接,然后开始发送数据,传输完成后关闭虚电路断开连接,因为TCP发送的数据包会等待对方确认,过一段时间没确认就会重新发送,所以能保证可靠交付,TCP能提供错误校验和,甄别数据错误

    3. TCP有连接,UDP无连接

    4. TCP会按照顺序重新排列数据包,UDP不会

    5. TCP会进行错误校验与恢复,UDP也会错误校验,但是会丢弃错误的包

    6. TCP有接受确认,UDP没有

    7. TCP三次握手建立连接: 首先是客户端向服务端发送SYN包(SYN值为1)并带上自己的seq=x作为序列号 => 服务端回复SYN+ACK包确认客户的确认号(ack=x+1),并带上自己的初始序列号seq=y => 客户端确认收到SYN+ACK并发送 ACK(seq=x+1,ack=y+1),

      SYN为1表示是请求连接,SYN为0表示是普通的数据传输,seq是发送者的序列号,ack是期望接收者下一次发送过来的序列号

    8. TCP四次挥手断开连接: 客户端发送FIN报文(seq=u)表示不再发送数据,但仍能接受数据 => 服务器接收FIN并发送ACK(seq=v,ack=u+1)告诉客户端收到了 => 服务器端发送完剩下的数据,主动向客户端发送FIN(seq=w,ack=u+1)并关闭自己发送方向 =>客户端接收FIN之后发送ACK(seq=u+1,ack=w+1)表示确认并等待一小段时间后断开连接,服务端接收ACK之后断开

    9. HTTP1.0 / HTTP1.1 / HTTP2.0 :

      1. HTTP1.0 : 最基本的认证,是短链接,即每次发送数据都要三次握手和四次挥手,不支持断点续传,认为一个计算机只能绑定一个IP所以发请求URL不带主机名
      2. HTTP1.1 : 使用摘要算法进行认证,长链接,一次链接可以发送多次数据,链接时长由请求头keep-alive设置,支持断点续传,使用虚拟网络,一台物理主机可以有多个虚拟主机共享一个IP地址
      3. HTTP2.0 : 使用HPACK算法压缩请求头,使用更加靠近TCP/IP协议的二进制格式,抛弃了ASCII码,提高解析效率,跟1.1一样是持久连接,但同时可以多路复用,即可以同时发送多个请求,HTTP2.0一般运行在HTTPS上

HTTPS:

  1. TLS握手是建立在TCP三次握手上的
  2. 先进行HTTP的三次握手,握手完成后再进行TLS的握手过程
  3. 客户端通过向服务器发送hello消息来发起握手过程,这个消息中会夹带着客户端支持的TLS版本号,客户端支持的密码套件,以及一串客户端随机数(用来后续生成密钥)
  4. 服务器接收到hello消息之后会发送一条消息,这条消息包含了服务器的SSL证书(包含公钥) ,服务器从客户端支持的密码套件中选择的密码套件,和服务器生成的随机数
  5. 认证: 客户端认证SSL证书,第一部分握手阶段结束
  6. 加密阶段: 第一阶段完成后,客户端制作一个随机字符串作为预主密钥用公钥进行加密然后发给服务端,
  7. 然后服务端用私钥解密得到预主密钥,然后客户端和服务端用相同的算法对预主密钥和一开始的客户端字符串,服务端字符串进行加密得到密钥
  8. 然后客户端发送finished(包含之前所有握手消息的哈希值来验证完整性)告诉服务端自己发送完成了
  9. 服务端发送加密的Finished

状态码

1xx : 信息

  1. 100 : 服务器愿意接收请求体,客户端应该继续发送请求,通常用于客户端在发送大请求体前先发送消息询问服务器是否愿意接收
  2. 101 : 服务器同意切换协议

2xx : 成功

  1. 200 : 请求成功,对于GET请求,响应中包含所请求的资源,对于POST/PUT等,通常返回操作结果
  2. 201 : 请求已成功,且服务器创建了新资源,并返回新资源地址,常用于POST或PUT请求
  3. 204 : 请求成功,但响应中没有实体内容,常用于DELETE或某些表单提交或CORS的跨域预检响应
  4. 206 : 服务器返回部分内容,用于断点续传或视频分段加载

3xx : 重定向

  1. 301 : 永久重定向,资源已经被分配了新的URI,今后所有的请求都应该使用新地址,浏览器会缓存这个重定向,后续直接访问新地址
  2. 302 : 临时重定向,资源暂时位于另一URI,客户端应继续使用原URI访问,常见于未登录跳转登录页
  3. 304 : 资源未修改,可使用缓存版本,客户端发送条件请求询问服务端资源是否被修改了,服务端如果没变化就返回304(无响应体)
  4. 307 : 临时重定向,且要求客户端保持原请求方法(如POST继续用POST),302在某些实现中可能将POST改为GET,现在更推荐使用307/308
  5. 308 : 永久重定向,保持原请求方法

4xx : 客户端错误

  1. 400 : 请求错误服务器无法理解
  2. 401 : 需要身份认证
  3. 403 : 能识别你的身份,但是权限不够
  4. 404 : 请求资源不存在
  5. 405 : 请求方法不允许(比如对只读资源使用POST),响应头应只包含Allow头列出支持方法
  6. 408 : 服务器超时
  7. 429 : 短时间请求过多被限流了

5xx : 服务器错误

  1. 500 : 服务器内部错误,这是通用服务器错误
  2. 502 : 代理服务器从上游服务器收到无效响应,比如后端服务挂掉
  3. 503 : 服务器过载或维护导致无法处理请求,一般是临时状态
  4. 504 : 代理服务等待上游服务器响应时超时

请求头与响应头

请求头:

  1. Host : 告诉我服务器你要访问哪个域名
  2. Cookie: 设置Cookie: Cookie的内容键值对,作为请求头是用来发送Cookie的
  3. Origin : 告诉服务器你从哪来(用于安全和CORS)
  4. Authorization : 带身份凭证,JWT等身份凭证,前端代码中通过fetch或XMLHttpRequest设置,开发者手动设置
  5. Content-Type : 发送POST/PUT的请求头的时候需要指明格式(application/json,multipart/form-data等)开发者手动设置
  6. Expect: 一般用于复杂Post请求分两次进行请求,Expect: 100 continue

响应头 : 由服务器配置

  1. Cache-Control: 设置强缓存
  2. ETag(响应头)/If-None-Match(请求头) : 设置协商缓存,根据数据内容计算出ETag,每次请求数据的时候在If-None-Match中携带ETag,如果没修改就返回304Not Modified,否则返回200+新资源
  3. Last-Modified(响应头)/If-Modified-Since(请求头) : 设置协商缓存
  4. Location: 设置重定向或创建资源后返回新地址
  5. Access-Control-Allow-Origin : CORS跨域配置,在后端用Access-Control-Allow-Origin: 地址 配置跨域
  6. Content-Encoding : 服务器如nginx配置启动gzip/Brotli压缩
  7. Set-Cookie : 为Cookie设置属性,比如SameSite属性,内容键值对,Expires等
  8. Connection: keep-alive(请求头/响应头) : 链接时长