# HTTP 协议

特点:简单快速,灵活,无连接无状态

无状态的意思是其数据包的发送、传输和接收都是相互独立的,无记忆的。无连接的意思是指通信双方都不长久的维持对方的任何信息。

# HTTP 协议报文组成

# 1. 请求报文组成

  • 请求行:http 方法、页面 url 地址、协议/版本;
  • 请求头:key-value;
  • 空行:分隔符 CRLF;
  • 请求体;

请求报文

常用请求头与响应头

常用请求头

  • Accept:代表发送端(客户端)希望接受的数据类型,可以为一个或多个 MIME 类型的值
  • Content-Type:代表发送端(客户端|服务器)发送的实体数据的数据类型 - application/x-www-form-urlencoded - application/json - multipart/form-data - text/xml
  • Cookie:包含 sessionId
  • Referer:表示这个请求是从哪个 URL 过来的
  • Cache-Control:no-cache
  • Connection:keep-alive
  • Host:初始 URL 中的主机和端口
  • User-Agent:浏览器类型

常用响应头

  • Cache-Control:max-age=3600
  • ETag
  • Location:
  • Set-Cookie:服务端可以设置客户端的 Cookie

# 2. 响应报文组成

  • 响应行:协议/版本、状态码;
  • 响应头:key-value;
  • 空行:分隔符 CRLF;
  • 响应体;

响应报文

# HTTP 方法

  • GET:获取资源
  • POST:传输资源
  • PUT:更新资源
  • DELETE:删除资源
  • HEAD:获取报文首部(报文头)

# GET 与 POST 的区别(关注前 5 点)

  1. GET 在浏览器回退时是不会重复提交的,而 POST 会再次提交请求
  2. GET 请求会被浏览器主动缓存,而 POST 不会,除非手动设置
  3. GET 请求参数会被完整保留在浏览器历史记录中,而 POST 中的参数不会被保留
  4. GET 参数通过 URL 传递,POST 放在 Request body 中
  5. GET 请求在 URL 中传参是有长度限制的(一般为 2kb),而 POST 没有限制
  6. get 会产生一个 tcp 数据包,而 post 产生两个,先发 headers 响应 100 continue,再发 data 响应 200
  7. GET 产生的 URL 地址可以被收藏,而 POST 不可以;
  8. GET 参数直接放在 URL 中,不能传递敏感信息;
  9. GET 只能进行 url 编码,而 POST 支持多种编码方式。

# HTTP 状态码及常用端口

# 状态码

  • 1xx:指示信息
  • 2xx:成功 - 200 OK:客户端请求成功
    • 204 No content:表示请求成功,但响应报文不含实体的主体部分 - 206 Partial Content:客户端发送带 Range 头的 Get 请求,服务器会按照 Range 截取对应数据返回,通常用于 video 标签或 audio 标签请求一个大的视音频文件时,返回 range 部分
  • 3xx:重定向 - 301 Moved Permanently:永久重定向,所请求的页面已经永久转移至新 url - 302 Found:临时性重定向,所请求的页面已经临时转移至新的 url - 303 和 307 是 HTTP1.1 新加的,它们是对 HTTP1.0 中的 302 状态码的细化 - 303,POST 重定向为 GET - 307,不会把 POST 转为 GET - 304 Not Modified:客户端存在缓存并且此缓存未被更改可继续使用
  • 4xx:客户端错误 - 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
    • 401 unauthorized:表示发送的请求缺少身份认证信息 - 403 Forbidden:对被请求页面的访问被禁止 - 404 Not Found:请求资源不存在
  • 5xx:服务器错误 - 500 Internal Server Error:服务器错误 - 503 Server Unavailable:服务器不可用,临时过载宕机,导致请求未完成

# ajax302 重定向跨域问题

ajax 发起的接口请求浏览器直接发起的页面访问请求 有一定区别:

  • 浏览器可以通过返回的 http 状态进行相应的操作,如访问一个页面,此页面 3xx 重定向时,浏览器可以获取到重定向后的 url,然后把地址栏的 url 替换,完成重定向动作
  • ajax 的目的就是无刷新的,所以对于服务器端进行了 3xx 重定向时,ajax 会获取到重定向状态值 3xx 和重定向 url,然后再此发送一个新请求去请求重定向 url。

因此,如果这个后端接口重定向给的 url 是另外一个域名的地址,那么此时就会出现跨域问题

解决方式是:ajax 在第一次得到相应处理后,主动通过js做一次location.href跳转目的是让浏览器去请求重定向的接口而不是 ajax

# 常用端口

  • http 80
  • https 443
  • DNS 53
  • FTP 20 21
  • SMTP 25
  • POP3 110

# 长连接(持久连接或连接重用)

# 概念

  • http1.1版本才支持的传输模式;
  • HTTP 协议采用“请求-应答”模式,分为普通模式keep-alive模式这两种模式;
  • 当使用普通模式时,每个请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开(HTTP协议为无连接的协议)。
  • 当使用Keep-alive模式时(又称持久连接或连接重用),keep-alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,keep-alive 功能避免了重新建立连接
  • 注意: keep-alive 不会永远保持,它有一个持续时间,一般在服务器中配置(如 apache),另外长连接需要客户端和服务器都支持时才有效。

# 从两个层面定义

# 先看 tcp/ip 层面的定义:

  • 长连接:一个 tcp/ip 连接上可以连续发送多个数据包,在 tcp 连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持(类似于心跳包)
  • 短连接:通信双方有数据交互时,就建立一个 tcp 连接,数据发送完成后,则断开此 tcp 连接

# 在 http 层面的定义:

  • http1.0中,默认使用的是短连接,也就是说,浏览器每进行一次 http 操作,就建立一次连接,任务结束就中断连接,譬如每一个静态资源请求时都是一个单独的连接
  • http1.1起,默认使用长连接,使用长连接会有这一行Connection: keep-alive,在长连接的情况下,当一个网页打开完成后,客户端和服务端之间用于传输 http 的 tcp 连接不会关闭,如果客户端再次访问这个服务器的页面,会继续使用这一条已经建立的连接

# 什么是管线化

  • 持久连接时,某个连接上消息的传递类似于:请求1-》响应1-》请求2-》响应2-》请求3-》响应3
  • 持久连接时,管线化是指某个连接上的消息传递类似于:请求1-》请求2-》请求3-》响应1-》响应2-》响应3(即打包一次发送多个请求,一次返回多个响应);
  • 管线化是在持久连接的情况下完成的,仅 http1.1 支持;
  • 只有 GET 和 HEAD 请求可以进行管线化;
  • 管线化不会影响响应到来的顺序;
  • 很多代理程序对管线化支持并不好,因此 Chrome 和 FF 默认并未开启管线化支持。初次创建连接时不应启动管线机制,因为对方服务器可能不支持。

# HTTP 2.0

http2.0 不是 https,它相当于是 http 的下一代规范(譬如 https 的请求可以是 http2.0 规范的)。

# http2.0 与 http1.1 的显著不同点:

  • http1.1 是一对一的:一个tcp/ip请求只能请求一个资源,由于 tcp/ip 本身有并发数限制,所以当资源一多,速度就显著慢下来;
  • http2.0 是一对多的:一个tcp/ip请求可以请求多个资源,也就是说,只要一次 tcp/ip 请求,就可以请求若干个资源,分割成更小的帧请求,速度明显提升。

所以,如果 http2.0 全面应用,很多 http1.1 中的优化方案就无需用到了(譬如打包成精灵图,静态资源多域名拆分等)。

# http2.0 特性

  • 多路复用(即一个 tcp/ip 连接可以请求多个资源);
  • 首部压缩(http 头部压缩,减少体积);
  • 服务器端推送server push(服务端可以对客户端的一个请求发出多个响应,可以主动通知客户端);
  • 二进制分帧(在应用层跟传送层之间增加了一个二进制分帧层,改进传输性能,实现低延迟和高吞吐量);
  • 请求优先级(如果流被赋予了优先级,它就会基于这个优先级来处理,由服务器决定需要多少资源来处理该请求)。

# https

  • https 其实就是身披 SSL 协议这层外壳的 http。https 并非是应用层的一种新协议,只是 https 通信接口部分用 SSL(Secure Socket Layer) 和 TLS(Transport Layer Security)协议代替而已。因此 https 又叫 HTTP over SSL, HTTP over TLS。
  • https 是 http 的安全版本,譬如一些支付等操作基本都是基于 https 的,因为 http 请求的安全系数太低了;
  • 简单来看,https 与 http 的区别就是:在请求前,会建立ssl链接,确保接下来的通信都是加密的,无法被轻易截取分析
  • 一般来说,如果要将网站升级成 https,需要后端支持(后端需要申请证书等),然后 https 的开销也比 http 要大(因为需要额外建立安全链接以及加密等),所以一般来说 http2.0 配合 https 的体验更佳(因为 http2.0 更快了)。

# https 是时代趋势

目前全球互联网正在从 HTTP 想 HTTPS 大迁移,Chrome 和火狐将对不采用 HTTPS 加密的网站提示不安全,苹果要求所有 APP 同学都必须采用 HTTPS 加密,小程序强制要求服务器端使用 HTTPS 请求。

# http 和 https 的区别

  1. https 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。(原来网易官网是 http,而网易邮箱是 https。)
  2. http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
  3. http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  4. http 的连接很简单,是无状态的。Https 协议是由 SSL+Http 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)

# CA 证书有哪些加密算法

非对称加密 对称加密 单向加密
RSA(如 git)、ECC(数字货币) DES、AES MD5
非对称加密是客户端用来向服务端传对称密钥的 对称加密用来双方传数据

# 对称加密和不对称加密的区别

  • 「对称加密」加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。
  • 「非对称加密」使用了一对密钥(公钥与私钥),所以安全性高,但加密与解密速度慢。

# CA 证书在客户端还是在服务端

服务器端的 CA 证书包含了非对称加密的公钥和私钥,将只包含公钥的证书发送给客户端。

# HTTPS 采用对称加密+非对称加密的混合方式

  • HTTPS 只在证书验证阶段使用「非对称加密」,在之后的内容传输阶段使用「对称加密」
  • 那为什么一开始用不对称,后面用对称加密呢?这正是因为二者特点所决定的: - 非对称加密的加解密效率是非常低的(计算复杂度高,极端情况下 1000 倍),对于大量数据交互来说这是无法接受的。 - 对称加密使用同样的密钥,并需要将密钥在网络传输,不安全。
  • 解决方式就是: - 客户端,https 将生成的随机数使用「非对称加密」公钥进行加密,然后发送出去; - 服务端使用「非对称加密」私钥进行解密,得到对称加密的密钥,然后双方可以使用对称加密来进行信息传输。

# https 的请求流程

  • 服务端发送公钥到 CA 认证中心,CA 会签发一个证书给服务端;
  • 客户端发起 HTTPS 请求,服务端返回证书+公钥
  • 客户端首先会拿证书去 CA 进行验证;
  • 验证通过后,本地生成用于改造对称加密算法的随机数;
  • 再通过证书中的公钥(「非对称加密」)对随机数进行加密得到随机数密钥(也就是对称密钥),传输到服务端;
  • 服务端接收后,通过私钥解密(「非对称解密」)得到随机数密钥
  • 之后的数据交互就可以通过随机数密钥(也就是对称密钥)执行「对称加密算法」了。

# 扩展:SSH 验证过程

SSH 验证过程比 https 的请求过程要简单一些:

  • 客户端通过某种方式,将公钥保存在服务端。
  • 当客户端要登录服务器时,会发送验证请求;
  • 服务器会用公钥加密一个随机数,传给客户端;
  • 客户端会使用私钥解密得到结果传给服务端,服务端比对完成验证。
Last Updated: 4/21/2021, 5:50:33 PM