1、什么是 HTTP 协议?有什么特点?

HTTP 协议是超文本传输协议的缩写,英文是 Hyper Text Transfer Protocol。它是从 WEB 服务器传输超文本标记语言(HTML)到本地浏览器的传送协议。

特点:

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径
  • 灵活:HTTP 允许传输任意类型的数据对象。传输的类型由 Content-Type 加以标记
  • 无连接:限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间,但是却不利于客户端与服务器保持会话连接,为了弥补这种不足,产生了两项记录 HTTP 状态的技术,一个叫做 Cookie,一个叫做 Session。
  • 无状态:是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态,每次 HTTP 请求都是独立的,任何两个请求之间没有什么必然的联系。

2、简单描述下 HTTP 连接建立流程

  1. 客户端和服务器端通过 TCP 三次握手建立双方连接;
  2. 客户端通过发送请求报文及请求数据给服务器端;
  3. 服务器端返回响应报文及响应数据给客户端;
  4. 客户端和服务器端通过 TCP 四次挥手断开连接。

3、说说 TCP 三次握手过程

  1. 第一次握手:建立连接时,客户端发送 SYN 包(seq=x)到服务器,并进入 SYN_SENT 状态, 等待服务器确认。(SYN:同步序列编号,Synchronize Sequence Numbers);
  2. 第二次握手:服务器收到 SYN 包,必须确认客户的 SYN(ack=x+1),同时自己也发送一个 SYN 包(seq=y),即 SYN + ACK 包,此时服务器进入 SYN_RECEVED 状态;
  3. 第三次握手:客户端收到服务器的 SYN + ACK 包,向服务器发送确认包 ACK(ack=y+1),此包发送完毕,客户端和服务器端进入 ESTABLISHED(TCP 连接成功)状态,完成三次握手。

**TCP 3-Way Handshake (SYN, SYN-ACK,ACK)**,TCP 三次握手流程图

tcp-3-way-handshake

TCP Header

TCP-Header-Format

TCP 有6中标志位:

  • SYN(synchronous 建立连接)
  • ACK(acknowledgement 确认)
  • PSH(push 传送)
  • FIN(finish 结束)
  • RST(reset 重置)
  • URG(urgent 紧急)

另外数据包:

  • Sequence number(顺序号码)
  • Acknowledge number(确认号码)
  1. 第一次握手中 SYN = 1,代表客户端 Client 要建立连接,同时随机产生 seq(Sequence number)= x 的数据包,然后传输到 Server;
  2. Server 收到 Client 的信息,通过 SYN = 1 知道是要建立连接,然后向 Client 发送信息,ACK = 1 代表确认,ack(Acknowledge number)= x + 1SYN = 1 代表建立连接,随机产生 seq = y 的数据包;
  3. Clien 收到 Server 的信息,通过 SYN = 1 知道是要建立连接,然后检查 ack 是否正确,即第一次发送的 seq + 1,同时检查 ACK 是否为 1,若正确,Client 再发送 ack = y + 1ACK = 1 到 Server,Server 收到确认 seq 值和 ACK = 1 后则连接建立成功。

4、为什么 TCP 连接要进行三次握手而不是两次握手?

防止服务器端的一直等待而浪费资源。

理解:假设 client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的传输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。”

为了保证服务端能接受到客户端的信息并能做出正确的应答而进行前两次(第一次和第二次)握手,为了保证客户端能够接收到服务端的信息并能做出正确的应答而进行后两次(第二次和第三次)握手。

5、TCP 四次挥手过程,为什么要四次挥手?

6、浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

Request Header 中 Connection 属性决定了连接是否持久,HTTP/1.0 中 Connection 默认是 close 的,即每次请求都会重新建立和断开 TCP 连接,而在 HTTP/1.1 中 Connection 默认是 keep-alive 的,即连接可以复用,不用每次都重新建立和断开 TCP 连接。如果想主动断开连接,只需要将 Connection 属性设置为 close 即可,即 Connection: close。一般情况下复用的 TCP 连接在等待设置的超时时间之后还没有被任何连接使用的话,TCP 连接就会主动断开。

7、一个 TCP 连接能发几个 HTTP 请求?

  • HTTP/1.0 中 Connection 默认是 close 的,即每次请求都会重新建立和断开 TCP 连接,因此一个 TCP 连接只能发1个 HTTP 请求
  • HTTP/1.1 中 Connection 默认是 keep-alive 的,即连接可以复用,不用每次都重新建立和断开 TCP 连接,因此只要 TCP 连接不断开,便可以一直发送 HTTP 请求,持续不断,没有上限
  • HTTP 2.0 支持多路复用,一个 TCP 连接是可以并发多个 HTTP 请求,同样也是支持长连接,因此只要不断开 TCP 的连接,HTTP 请求数也是可以没有上限地持续发送

8、一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?

  • HTTP/1.0 一个 TCP 连接只能发1个 HTTP 请求,因此不可以
  • HTTP/1.1 在同一时刻只能处理一个请求,即两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠,收到请求的服务器必须按照请求收到的顺序发送响应。通过 Pipelining 技术可以实现一个 TCP 连接发送多个 HTTP 请求,但是由于浏览器默认关闭,因此可以认为这是不可行的
  • HTTP/2.0 提供了 Multiplexing 多路传输特性,可以在一个 TCP 连接中同时完成多个 HTTP 请求

在 HTTP/1.1 存在 Pipelining 技术可以完成这个多个请求同时发送,但是由于浏览器默认关闭,所以可以认为这是不可行的

HTTP pipelining is a technique in which multiple HTTP requests are sent on a single TCP (transmission control protocol) connection without waiting for the corresponding responses.
The technique was superseded by multiplexing via HTTP/2, which is supported by most modern browsers.
As of 2018, HTTP pipelining is not enabled by default in modern browsers, due to several issues including buggy proxy servers and HOL blocking.

在 HTTP/1.1 时代,浏览器提高页面加载效率主要通过下面两点:

  • 维持和服务器已经建立的 TCP 连接,在同一连接上顺序处理多个请求。
  • 和服务器建立多个 TCP 连接。

9、浏览器对同一 Host 建立 TCP 连接的数量有没有限制?

有,Chrome 最多允许对同一个 Host 建立六个 TPC 连接,不用的浏览器有一些不同。

10、TCP 与 UDP 有什么区别?

  1. 连接与无连接
    • TCP 是基于连接的传输方式,发送数据之前需要先建立连接;
    • UDP 发送数据之前不需要建立连接。
  2. 正确性与丢包
    • TCP 传送数据可靠,无差错,不丢失,不重复,且按序到达;
    • UDP 不保证传送数据可靠,尽最大努力交付。
  3. 流模式与数据报模式
    • TCP 面向字节流,TCP 把数据看成一连串无结构的字节流;
    • UDP 面向报文,没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)。
  4. 点到点及多点互联
    • 每一条 TCP 连接只能是点到点的;
    • UDP 支持一对一,一对多,多对一和多对多的交互通信。
  5. 资源要求多和少
    • TCP 首部开销20字节;
    • UDP 的首部开销小,只有8个字节。
  6. 信道可靠和不可靠
    • TCP 的逻辑通信信道是全双工的可靠信道;
    • UDP 则是不可靠信道。

UDP(User Datagram Protocol,用户数据包协议),是一个简单的面向数据报的通信协议,UDP 只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份

简版:

  1. TCP是一个面向连接的、可靠的、基于字节流的传输层协议。
  2. UDP是一个面向无连接的传输层协议。

TCP为什么可靠,是因为它有三次握手来保证双方都有接受和发送数据的能力。

字节流服务:将大块数据分割为以报文段为单位的数据包进行管理

11、什么是 HTTPS? 与 HTTP 相比有什么区别?

HTTPS 是在 HTTP 上建立 SSL 加密层,并对传输数据进行加密,是 HTTP 协议的安全版。现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层与应用层之间对网络连接进行加密。

HTTPS 主要作用是:

  • 对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;
  • 对网站服务器进行真实身份认证。

与 HTTP 的区别:

  1. 是否免费
    • HTTPS 协议需要到 CA(证书颁发机构,Certificate Authority)申请证书,一般免费证书较少,因而需要一定费用;
    • HTTP 一般是免费的。
  2. 安全性
    • HTTP 协议运行在 TCP 之上,所有传输的内容都是明文;
    • HTTPS 运行在 SSL/TLS 之上,SSL/TLS 运行在 TCP 之上,所有传输的内容都经过加密的。
  3. 连接方式与复杂度
    • HTTP 的连接很简单,是无状态的;
    • HTTPS 协议是 SSL + HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。
  4. 端口不同
    • HTTP 使用的端口号是 80;
    • HTTPS 使用的端口号是 443。

12、HTTPS 的加密方式是什么?

HTTPS 的加密方式:对称加密 + 非对称加密 + 证书。 服务器用明文的方式给客户端发送自己的公钥,客户端收到公钥之后,会生成一把密钥(对称加密用的),然后用服务器的公钥对这把密钥进行加密,之后再把密钥传输给服务器,服务器收到之后进行解密,最后服务器就可以安全得到这把密钥了,而客户端也有同样一把密钥,他们就可以进行对称加密了。

  1. 对称加密

    需要对加密和解密使用相同密钥的加密算法。所谓对称,就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解密过程的指令。算法是一组规则,规定如何进行加密和解密。

  2. 非对称加密 RSA

    非对称加密算法需要两个密钥:公开密钥(publickey: 简称公钥)和私有密钥(privatekey: 简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

非对称性加密之所以不安全,是应为客户端不知道,这把公钥是不是服务器的。因此,我们需要找到一种策略来证明这把公钥就是服务器的,而不是别人冒充的。解决这个问题的方式就是使用数字证书,具体是这样的:

1、我们需要找到一个第三方机构,它是一个拥有公信力、大家都认可的认证中心,那就是数字证书认证机构(简称CA)**。 2、服务器在给客户端传输公钥的过程中,会把公钥以及服务器的个人信息通过Hash算法生成信息摘要。为了防止信息摘要被人调换,客户端还会用CA提供的私钥对信息摘要进行加密来形成数字签名。并且,最后还会把原来没Hash算法之前的个人信息以及公钥和数字签名合并在一起,形成数字证书**。 3、当客户端拿到这份数字证书之后,就会用CA提供的公钥来对数字证书里面的数字签名进行解密来得到信息摘要,然后对数字证书里服务器的公钥以及个人信息进行Hash得到另外一份信息摘要。最后把两份信息摘要进行对比,如果一样,则证明这个人是服务器,否则就不是。这样,就可以保证服务器的公钥安全着交给客户端了。

  • 服务器
    • 服务器的(公钥 + 个人信息)通过 Hash 算法生成 信息摘要
    • 信息摘要 通过 CA 提供的私钥加密形成 数字签名
    • 未 Hash 算法过的(公钥 + 个人信息)+ 数字签名 合并形成 数字证书
  • 客户端
    • CA 提供的公钥解密数字证书中的 数字签名 得到 信息摘要
    • 数字证书中的(公钥 + 个人信息)通过 Hash 算法生成 信息摘要
    • 对比两份信息摘要

HTTPS 的加密方式

13、状态码都有哪些?304是指什么意思

1xx

  • 101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。

2xx 成功

  • 200 成功

  • 206 Partial Content

    服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解成多个下载段同时下载。该请求必须包含 Range 头信息来指示客户端希望得到的内容范围,并且可能包含 If-Range 来作为请求条件。

3xx 重定向

  • 301 Moved Permanently,永久重定向
  • 302 临时重定向
  • 303 重定向
  • 304 not modified, 表示资源未修改,浏览器使用本次缓存资源。(协商缓存)

4xx 前端错误

  • 400 bad request, 错误请求,服务器不理解请求的语法,一般是前端请求数据格式有误
  • 401 Unauthorized, 未授权,请求要求身份验证
  • 403 Forbidden, 服务器拒绝请求
  • 404 Not found, 服务器找不到请求的网页
  • 405 Method Not Allowed,请求方法(GET、POST、PUT等)对指定的资源不适用,用来访问本资源的HTTP方法不被允许

5xx 服务器异常

  • 500 Internal Server Error,服务器内部运行错误
  • 502 bad gateway,错误网关
  • 503 Service Unavailable,服务不可用,服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态
  • 504 Gateway Timeout,网关超时,一般是网络不稳定导致的

HTTP 状态码详细

304协商缓存

浏览器缓存分为强制缓存和协商缓存,优先读取强制缓存。

  • 强制缓存分为 expires 和 cache-control,expires 是一个特定的时间,是比较陈旧的标准,是比较旧的标准,而 cache-control 通场是一个具体的时间长度,比较新,优先级也比较高
  • 协商缓存包括 etag 和 last-modified,last-modified 的设置标准是资源的上次修改时间,而 etag 是为了应对资源修改时间可能很频繁的情况出现的,是基于资源的内容计算出来的值,因此优先级较高
  • 协商缓存与强制缓存的区别在于强制缓存不需要访问服务器,返回结果是200,协商缓存需要访问服务器,命中协商缓存的话,返回结果是304

301和302有什么区别?

  • 301表示被请求 url 永久转移到新的 url;302表示被请求 url 临时转移到新的 url。
  • 301搜索引擎会索引新 url 和新 url 页面的内容;302搜索引擎可能会索引旧 url 和新 url 的页面内容。
  • 302的返回码可能被别人利用,劫持你的网址。因为搜索引擎索引他的网址,他返回302跳转到你的页面。

使用301跳转的场景:

  • 域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
  • 在搜索引擎的搜索结果中出现了不带 www 的域名,而带 www 的域名却没有收录,这个时候可以用301重定向来告诉搜索引擎我们目标的域名是哪一个。
  • 空间服务器不稳定,换空间的时候。

使用302跳转的场景:

  • 尽量使用301跳转!因为302网址劫持会造成网址劫持

302 重定向和网址劫持(URL hijacking) 从网址A做一个302重定向到网址B时,主机服务器的隐含意思是网址A随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302转向时,百分之百的都抓取目标网址B的话,就不用担心网址URL劫持了。问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。比如说,有的时候A网址很短,但是它做了一个302重定向到B网址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不能用户友好。这时Google很有可能会仍然显示网址A。由于搜索引擎排名算法只是程序而不是人,在遇到302重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址URL劫持的可能性。也就是说,一个不道德的人在他自己的网址A做一个302重定向到你的网址B,出于某种原因,Google搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B上的内容,这种情况就叫做网址URL劫持。你辛辛苦苦所写的内容就这样被别人偷走了。302重定向所造成的网址URL 劫持现象,已经存在一段时间了。不过到目前为止,似乎也没有什么更好的解决方法。在谷歌曾进行的Big Daddy数据中心转换中,302重定向问题也是要被解决的目标之一。从一些搜索结果来看,网址劫持现象有所改善,但是并没有完全解决。

14、HTTP2.0 有哪些新特性?

  • 新的二进制格式(Binary Format),HTTP1.x 的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认 0 和 1 的组合。基于这种考虑 HTTP2.0 的协议解析决定采用二进制格式,实现方便且健壮。
  • 多路复用(MultiPlexing),即连接共享,即每一个 request 都是是用作连接共享机制的。一个 request 对应一个 id,这样一个连接上可以有多个 request,每个连接的 request 可以随机的混杂在一起,接收方可以根据 request 的 id 将 request 再归属到各自不同的服务端请求里面。
  • header 压缩, HTTP1.x 的 header 带有大量信息,而且每次都要重复发送,HTTP2.0 使用 encoder 来减少需要传输的 header 大小,通讯双方各自 cache 一份 header fields 表,既避免了重复 header 的传输,又减小了需要传输的大小。
  • 服务端推送(server push),例如我的网页有一个 sytle.css 的请求,在客户端收到 sytle.css 数据的同时,服务端会将 sytle.js 的文件推送给客户端,当客户端再次尝试获取 sytle.js 时就可以直接从缓存中获取到,不用再发请求了。

15、浏览器的缓存机制是什么,怎么实现缓存?

良好的缓存策略可以降低资源的重复加载提高网页的整体加载速度。
通常浏览器缓存策略分为两种:强缓存和协商缓存。

  1. 浏览器发送请求前,根据请求头的 expires 和 cache-control 判断是否命中(包括是否过期)强缓存策略,如果命中,直接从缓存获取资源,并不会发送请求。如果没有命中,则进入下一步。
  2. 没有命中强缓存规则,浏览器会发送请求,根据请求头的 last-modified 和 etag 判断是否命中协商缓存,如果命中,直接从缓存获取资源。如果没有命中,则进入下一步。
  3. 如果前两步都没有命中,则直接从服务端获取资源。

强缓存

  1. Expires
  2. Cache-Control

协商缓存

  1. Last-Modified -> If-Modified-Since
  2. ETag -> If-None-Match

浏览器缓存机制:强缓存、协商缓存

16、HTTP 和 TCP 的不同

  • HTTP 的责任是去定义数据,在两台计算机相互传递信息时,HTTP 规定了每段数据以什么形式表达才是能够被另外一台计算机理解
  • TCP 规定的是数据应该怎么传输才能稳定且高效的传递于计算机之前

17、从输入 URL 到页面的呈现,中间经历了什么?

简单版:

  1. 浏览器根据请求的 url 交给 dns 域名解析,查找真正的 ip 地址,向服务器发起 http 请求;
  2. 服务器交给后台处理后,返回数据,浏览器会接收到文件数据,比如,html,js,css,图像等;
  3. 然后浏览器会对加载到的资源进行语法解析,建立相应的内部数据结构;
  4. 载入解析到得资源文件,渲染页面,完成显示页面效果。

详细版涉及知识点: 从输入URL到页面加载的过程?

  1. 从浏览器接收 url 到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的关系)
  2. 开启网络线程到发出一个完整的 http 请求(这一部分涉及到 dns 查询,tcp/ip 请求,五层因特网协议栈等知识)
  3. 从服务器接收到请求到对应后台接收到请求(这一部分可能涉及到负载均衡,安全拦截以及后台内部的处理等等)
  4. 后台和前台的 http 交互(这一部分包括 http 头部、响应码、报文结构、cookie 等知识,可以提下静态资源的 cookie 优化,以及编码解码,如 gzip 压缩等)
  5. 单独拎出来的缓存问题,http 的缓存(这部分包括 http 缓存头部,etag,catch-control 等)
  6. 浏览器接收到 http 数据包后的解析流程(解析 html-词法分析然后解析成 dom 树、解析 css 生成 css 规则树、合并成 render 树,然后 layout、painting 渲染、复合图层的合成、GPU 绘制、外链资源的处理、loaded 和 domcontentloaded 等)
  7. CSS 的可视化格式模型(元素的渲染规则,如包含块,控制框,BFC,IFC 等概念)
  8. JS 引擎解析过程(JS 的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)
  9. 其它(可以拓展不同的知识模块,如跨域,web 安全,hybrid 模式等等内容)

18、为什么 HTTP1.1 不能实现多路复用

HTTP/1.1 不是二进制传输,而是通过文本进行传输。由于没有流的概念,在使用并行传输(多路复用)传递数据时,接收端在接收到响应后,并不能区分多个响应分别对应的请求,所以无法将多个响应的结果重新进行组装,也就实现不了多路复用。

多路复用归功于, HTTP/2 中的 帧(frame)和流(stream)。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。就是在一个 TCP 连接中可以存在多条流。

而Http 1.x 并没有这个标识,每次请求都会建立一次HTTP连接,3次握手4次挥手。

19、get和post的区别

GET 请求只能 URL 编码,而 POST 支持多种编码方式

GET 请求只接受 ASCII 字符的参数,而 POST 则没有限制

GET 请求的参数通过 URL 传送,而 POST 放在 Request Body 中

GET 相对于 POST 更不安全,因为参数直接暴露在 URL 中

GET 请求会被浏览器主动缓存,而 POST 不会(除非自己手动设置)

GET 请求在 URL 传参有长度限制,而 POST 则没有限制

GET 产生的 URL 地址可以被收藏,而 POST 不可以

GET 请求的参数会被完整的保留在浏览器的历史记录里,而 POST 的参数则不会

GET 在浏览器回退时是无害的,而 POST 会再次提交请求

幂等性(如果一个操作没有副作用,或者多次操作对资源产生的副作用相同,我们就说这个操作是幂等的)

  • get方法获取资源,没有副作用,所以是幂等的

  • post用于创建资源,是有副作用的,且副作用不同,所以post不是幂等的

参考连接