精华内容
下载资源
问答
  • 小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。HTTP 基本概念Get 与 PostHTTP 特性...

    作者 | 小林coding
    来源 | 小林coding

    在面试过程中,HTTP 被提问的概率还是比较高的。
    小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。

    1. HTTP 基本概念
    2. Get 与 Post
    3. HTTP 特性
    4. HTTPS 与 HTTP
    5. HTTP/1.1、HTTP/2、HTTP/3 演变

    293a7331141d4243b969e87841e2849f.png

    d649d185408ab3df98834eb1e643756b.png

    HTTP 基本概念
    HTTP 是什么?描述一下
    HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。
    能否详细解释「超文本传输协议」?
    HTTP的名字「超文本协议传输」,它可以拆成三个部分:

    • 超文本
    • 传输
    • 协议

    17717cb7b81f3b095fd2e9cdf35b084e.png

    1. 「协议」
    在生活中,我们也能随处可见「协议」,例如:

    • 刚毕业时会签一个「三方协议」;
    • 找房子时会签一个「租房协议」;

    48d6c88bf80bbc5b19dba6c016eea116.png

    生活中的协议,本质上与计算机中的协议是相同的,协议的特点:

    • 「协」字,代表的意思是必须有两个以上的参与者。例如三方协议里的参与者有三个:你、公司、学校三个;租房协议里的参与者有两个:你和房东。
    • 「仪」字,代表的意思是对参与者的一种行为约定和规范。例如三方协议里规定试用期期限、毁约金等;租房协议里规定租期期限、每月租金金额、违约如何处理等。

    针对 HTTP 协议,我们可以这么理解。
    HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)。2. 「传输」
    所谓的「传输」,很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点 搬到 A 点。
    别轻视了这个简单的动作,它至少包含两项重要的信息。
    HTTP 协议是一个双向协议
    我们在上网冲浪时,浏览器是请求方 A ,百度网站就是应答方 B。双方约定用 HTTP 协议来通信,于是浏览器把请求数据发送给网站,网站再把一些数据返回给浏览器,最后由浏览器渲染在屏幕,就可以看到图片、视频了。

    05b3292dd25789b9094e4f7256fc9e7a.png

    数据虽然是在 A 和 B 之间传输,但允许中间有中转或接力。
    就好像第一排的同学想穿递纸条给最后一排的同学,那么传递的过程中就需要经过好多个同学(中间人),这样的传输方式就从「A < --- > B」,变成了「A <-> N <-> M <-> B」。
    而在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。
    针对传输,我们可以进一步理解了 HTTP。
    HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。3. 「超文本」
    HTTP 传输的内容是「超文本」。
    我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」。的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算做「文本」。
    再来理解「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体最关键有超链接,能从一个超文本跳转到另外一个超文本。
    HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。
    OK,经过了对 HTTP 里这三个名词的详细解释,就可以给出比「超文本传输协议」这七个字更准确更有技术含量的答案:HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。
    那「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议HTTP」 ,这种说法正确吗?
    这种说法是不正确的。因为也可以是「服务器< -- >服务器」,所以采用两点之间的描述会更准确。
    HTTP 常见的状态码,有哪些?

    b32569b71e0d86cd4a20b4e581eb9629.png

    1xx
    1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。2xx
    2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
    「200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。
    「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
    「206 Partial Content」是应用于 HTTP 分块下载或断电续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。3xx
    3xx 类状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
    「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
    「302 Moved Permanently」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
    301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
    「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。4xx
    4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
    「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
    「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
    「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。5xx
    5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
    「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
    「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
    「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
    「503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。
    http 常见字段有哪些?Host
    客户端发送请求时,用来指定服务器的域名。

    e6a0db4e19c9e269622b973c3f527df7.png

    Host: http://www.A.com
    有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站。Content-Length 字段
    服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度。

    c19d06e7d5cbef45d11891721e2c7386.png


    Content-Length: 1000
    如上面则是告诉浏览器,本次服务器回应的数据长度是 1000 个字节,后面的字节就属于下一个回应了。Connection 字段
    Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。

    3273c097f8e6333833ed4a4f6b2d55a7.png

    HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive。
    Connection: keep-alive
    一个可以复用的 TCP 连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段。Content-Type 字段
    Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。

    814a6e4ee0dd0d32fbddf3ef869fc2bf.png

    Content-Type: text/html; charset=utf-8
    上面的类型表明,发送的是网页,而且编码是UTF-8。
    客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。
    Accept: */*
    上面代码中,客户端声明自己可以接受任何格式的数据。Content-Encoding 字段
    Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式

    af35a6048fc3acf9e7c50520de2f9b26.png

    Content-Encoding: gzip
    上面表示服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。
    客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。
    Accept-Encoding: gzip, deflate

    60b9275a8d981884f14dfa8fbf500e4a.png

    GET 与 POST
    说一下 GET 和 POST 的区别?
    Get 方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。
    比如,你打开我的文章,浏览器就会发送 GET 请求给服务器,服务器就会返回文章的所有文字及资源。

    adc46f0d3105aa2dc71e094f4eea13fe.png

    而POST 方法则是相反操作,它向 URI 指定的资源提交数据,数据就放在报文的 body 里。
    比如,你在我文章底部,敲入了留言后点击「提交」(暗示你们留言),浏览器就会执行一次 POST 请求,把你的留言文字放进了报文 body 里,然后拼接好 POST 请求头,通过 TCP 协议发送给服务器。

    bee0e97948b4c7103b87686c3d442a36.png

    GET 和 POST 方法都是安全和幂等的吗?
    先说明下安全和幂等的概念:

    • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
    • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

    那么很明显 GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。
    POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的

    e943548e55404dac35db8fda6427bb17.png

    HTTP 特性
    你知道的 HTTP(1.1) 的优点有哪些,怎么体现的?HTTP 最凸出的优点是「简单、灵活和易于扩展、应用广泛和跨平台」。1. 简单
    HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解,降低了学习和使用的门槛。2. 灵活和易于扩展
    HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充。
    同时 HTTP 由于是工作在应用层( OSI 第七层),则它下层可以随意变化。
    HTTPS 也就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层,HTTP/3 甚至把 TCPP 层换成了基于 UDP 的 QUIC。3. 应用广泛和跨平台
    互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用片地开花,同时天然具有跨平台的优越性。
    那它的缺点呢?
    HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」。1. 无状态双刃剑
    无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。
    无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。
    例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。
    这样每操作一次,都要验证信息,这样的购物体验还能愉快吗?别问,问就是酸爽!
    对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。
    Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
    相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了,

    ee5778c3116197c9382adc605eeaf72a.png

    2. 明文传输双刃剑
    明文意味着在传输过程中的信息,是可方便阅读的,通过浏览器的 F12 控制台或 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。
    但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取,如果里面有你的账号密码信息,那你号没了。3. 不安全
    HTTP 比较严重的缺点就是不安全:

    • 通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了。
    • 不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了。
    • 无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了。

    HTTP 的安全问题,可以用 HTTPS 的方式解决,也就是通过引入 SSL/TLS 层,使得在安全上达到了极致。
    那你说下 HTTP/1.1 的性能如何?
    HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。1. 长连接
    早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无畏的 TCP 连接建立和断开,增加了通信开销。
    为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
    持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

    bb2d96062768514a7d2cb51f929b8f09.png

    2. 管道网络传输
    HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。
    即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。
    举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求。

    c941ad54d0c5c17d7cea1986c4c28d02.png

    但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」。3. 队头阻塞
    「请求 - 应答」的模式加剧了 HTTP 的性能问题。
    因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」。好比上班的路上塞车。

    e08608fed7ff057442907d760aedb720.png

    总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。

    8c2ee824ee464c09cf0ab8a495f4f92d.png

    HTTP 与 HTTPS
    HTTP 与 HTTPS 有哪些区别?

    1. HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
    2. HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
    3. HTTP 的端口号是 80,HTTPS 的端口号是 443。
    4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

    HTTPS 解决了 HTTP 的哪些问题?
    HTTP 由于是明文传输,所以安全上存在以下三个风险:

    • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
    • 篡改风险,比如强制入垃圾广告,视觉污染,用户眼容易瞎。
    • 冒充风险,比如冒充淘宝网站,用户钱容易没。

    HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议。

    273282d6ac45a5e70a0957e870d40807.png


    HTTP 与 HTTPS可以很好的解决了上述的风险:

    • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
    • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
    • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

    可见,只要自身不做「恶」,SSL/TLS 协议是能保证通信是安全的。
    HTTPS 是如何解决上面的三个风险的?

    • 混合加密的方式实现信息的机密性,解决了窃听的风险。
    • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
    • 将服务器公钥放入到数字证书中,解决了冒充的风险。

    1. 混合加密
    通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

    bf6974ccdab8d6b93941e9dc1182400f.png

    HTTPS 采用的是对称加密和非对称加密结合的「混合加密」方式:

    • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
    • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

    采用「混合加密」的方式的原因:

    • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
    • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

    2. 摘要算法
    摘要算法用来实现完整性,能够为数据生成独一无二的「指纹」,用于校验数据的完整性,解决了篡改的风险。

    707d26912f7ac0051ee5493cf4465fbc.png

    客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同
    加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。3. 数字证书
    客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
    这就存在些问题,如何保证公钥不被篡改和信任度?
    所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

    1034074b582551c98a3b2edda70c36c9.png

    通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。
    HTTPS 是如何建立连接的?其间交互了什么?
    SSL/TLS 协议基本流程:

    • 客户端向服务器索要并验证服务器的公钥。
    • 双方协商生产「会话秘钥」。
    • 双方采用「会话秘钥」进行加密通信。

    前两步也就是 SSL/TLS 的建立过程,也就是握手阶段。
    SSL/TLS 的「握手阶段」涉及四次通信,可见下图:

    4f28996819c106cd719e5357c6caffdc.png

    SSL/TLS 协议建立的详细流程:1. ClientHello
    首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。
    在这一步,客户端主要向服务器发送以下信息:
    (1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。
    (2)客户端生产的随机数(Client Random),后面用于生产「会话秘钥」。
    (3)客户端支持的密码套件列表,如 RSA 加密算法。2. SeverHello
    服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:
    (1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。
    (2)服务器生产的随机数(Server Random),后面用于生产「会话秘钥」。
    (3)确认的密码套件列表,如 RSA 加密算法。
    (4)服务器的数字证书。3.客户端回应
    客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。
    如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
    (1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。
    (2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
    (3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
    上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。4. 服务器的最后回应
    服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息:
    (1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
    (2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
    至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。

    8a0a47874e16559d283fba3ce666cf5d.png

    HTTP/1.1、HTTP/2、HTTP/3 演变
    说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能?
    HTTP/1.1 相比 HTTP/1.0 性能上的改进:

    • 使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
    • 支持 管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

    但 HTTP/1.1 还是有性能瓶颈:

    • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;
    • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
    • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
    • 没有请求优先级控制;
    • 请求只能从客户端开始,服务器只能被动响应。

    那上面的 HTTP/1.1 的性能瓶颈,HTTP/2 做了什么优化?
    HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。
    那 HTTP/2 相比 HTTP/1.1 性能上的改进:1. 头部压缩
    HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分。
    这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。2. 二进制格式
    HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式。
    头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧。

    25cb431f3f5168fa539be3335526668b.png

    这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率。3. 数据流
    HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
    每个请求或回应的所有数据包,称为一个数据流(Stream)。
    每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数
    客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。

    cb2251f0ca7a074c481e341ea98fed8d.png

    4. 多路复用
    HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。
    移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率。
    举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分。

    a13c06662bfe5645e1569a50ffb03e11.png

    5. 服务器推送
    HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。
    举例来说,在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。
    HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?
    HTTP/2 主要的问题在于:多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。
    所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。

    • HTTP/1.1 中的管道( pipeline)传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了
    • HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。

    这都是基于 TCP 传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

    d17b85f2a402fdde2145818a6572e6f5.png

    UDP 发生是不管顺序,也不管丢包的,所以不会出现 HTTP/1.1 的队头阻塞 和 HTTP/2 的一个丢包全部重传问题。
    大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

    • QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响。
    • TL3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPack。
    • HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3 的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数。

    214f600a7e34cf4de67c132dc2e39129.png

    所以, QUIC 是一个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议。
    QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。
    唠叨
    接近 30 张图片,都是从一条线两条线画出来,灰常的费劲,深切感受到画图也是个体力活啊!
    爱偷懒的我其实不爱画图,但为了让大家能更好的理解,在跟自己无数次斗争后,踏上了耗时耗体力的画图的不归路,希望对你们有帮助!
    创造不易啊,画图也不易,各位「三连」走起就是对小林创造的最大支持和动力了,我们下次见!

    参考文献:
    [1] 上野 宣.图解HTTP.人民邮电出版社.
    [2] 罗剑锋.透视HTTP协议.极客时间.
    [3] 陈皓.HTTP的前世今.酷壳CoolShell.https://coolshell.cn/articles/19840.html
    [4] 阮一峰.HTTP 协议入门.阮一峰的网络日志.http://www.ruanyifeng.com/blog/2016/08/http.html

    金三银四招聘季,你还有哪些面试干货文章呢?分享或者查看干货文章可戳:https://blog.csdn.net/blogdevteam/article/details/104691837

    展开全文
  • 小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。HTTP 基本概念Get 与 PostHTTP 特性...

    前言

    在面试过程中,HTTP 被提问的概率还是比较高的。

    小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。

    1. HTTP 基本概念
    2. Get 与 Post
    3. HTTP 特性
    4. HTTPS 与 HTTP
    5. HTTP/1.1、HTTP/2、HTTP/3 演变
    1c482aa4cc6fd4ed9fb122130499f64d.png

    提纲


    正文

    01 HTTP 基本概念

    HTTP 是什么?描述一下

    HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。

    能否详细解释「超文本传输协议」?

    HTTP的名字「超文本协议传输」,它可以拆成三个部分:

    • 超文本
    • 传输
    • 协议
    96c06ea7d93c16e3ed93af37c2702ef7.png

    三个部分

    1. 「协议」

    在生活中,我们也能随处可见「协议」,例如:

    • 刚毕业时会签一个「三方协议」;
    • 找房子时会签一个「租房协议」;
    5ccb7358a839559f562256b0752e8a8a.png

    三方协议和租房协议

    生活中的协议,本质上与计算机中的协议是相同的,协议的特点:

    • 」字,代表的意思是必须有两个以上的参与者。例如三方协议里的参与者有三个:你、公司、学校三个;租房协议里的参与者有两个:你和房东。
    • 」字,代表的意思是对参与者的一种行为约定和规范。例如三方协议里规定试用期期限、毁约金等;租房协议里规定租期期限、每月租金金额、违约如何处理等。

    针对 HTTP 协议,我们可以这么理解。

    HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)。

    2. 「传输」

    所谓的「传输」,很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点 搬到 A 点。

    别轻视了这个简单的动作,它至少包含两项重要的信息。

    HTTP 协议是一个双向协议

    我们在上网冲浪时,浏览器是请求方 A ,百度网站就是应答方 B。双方约定用 HTTP 协议来通信,于是浏览器把请求数据发送给网站,网站再把一些数据返回给浏览器,最后由浏览器渲染在屏幕,就可以看到图片、视频了。

    29e8ff978c2a690a11ae5ef5a57e9fc4.png

    请求 - 应答

    数据虽然是在 A 和 B 之间传输,但允许中间有中转或接力

    就好像第一排的同学想穿递纸条给最后一排的同学,那么传递的过程中就需要经过好多个同学(中间人),这样的传输方式就从「A < --- > B」,变成了「A N M B」。

    db840a6a445e63b90907ed6e365abb5f.gif

    而在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。

    针对传输,我们可以进一步理解了 HTTP。

    HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。

    3. 「超文本」

    HTTP 传输的内容是「超文本」。

    我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」。的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算做「文本」。

    再来理解「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体最关键有超链接,能从一个超文本跳转到另外一个超文本。

    HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。

    OK,经过了对 HTTP 里这三个名词的详细解释,就可以给出比「超文本传输协议」这七个字更准确更有技术含量的答案:

    HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。

    那「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议HTTP」 ,这种说法正确吗?

    这种说法是不正确的。因为也可以是「服务器< -- >服务器」,所以采用两点之间的描述会更准确。

    HTTP 常见的状态码,有哪些?

    a6cbff7d4edeef1c5af2bbb6856618ba.png

    五大类 HTTP 状态码

    1xx

    1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。

    2xx

    2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

    200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。

    204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。

    206 Partial Content」是应用于 HTTP 分块下载或断电续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。

    3xx

    3xx 类状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向

    301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。

    302 Moved Permanently」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。

    301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

    304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。

    4xx

    4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。

    400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。

    403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。

    404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

    5xx

    5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

    500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。

    501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。

    502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。

    503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

    http 常见字段有哪些?

    Host

    客户端发送请求时,用来指定服务器的域名。

    c322318e024491b1affd27551183e937.png
    Host: www.A.com

    有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站。

    Content-Length 字段

    服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度。

    6637fee6474cc3913c00c452057f35ab.png
    Content-Length: 1000

    如上面则是告诉浏览器,本次服务器回应的数据长度是 1000 个字节,后面的字节就属于下一个回应了。

    Connection 字段

    Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。

    6f2e09319913ca19fc0ea7c0a0f5777f.png

    HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定Connection 首部字段的值为 Keep-Alive。

    Connection: keep-alive

    一个可以复用的 TCP 连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段。

    Content-Type 字段

    Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。

    ecb01b8e834249a9b8f02ea40bf3c815.png
    Content-Type: text/html; charset=utf-8

    上面的类型表明,发送的是网页,而且编码是UTF-8。

    客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。

    Accept: */*

    上面代码中,客户端声明自己可以接受任何格式的数据。

    Content-Encoding 字段

    Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式

    ea19077f87078a4fe39dc3d3cff5102e.png
    Content-Encoding: gzip

    上面表示服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。

    客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。

    Accept-Encoding: gzip, deflate

    GET 与 POST

    说一下 GET 和 POST 的区别?

    Get 方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。

    比如,你打开我的文章,浏览器就会发送 GET 请求给服务器,服务器就会返回文章的所有文字及资源。

    fe87eaebedfc640aabc3f188d35870c9.png

    GET 请求

    而POST 方法则是相反操作,它向 URI 指定的资源提交数据,数据就放在报文的 body 里。

    比如,你在我文章底部,敲入了留言后点击「提交」(暗示你们留言),浏览器就会执行一次 POST 请求,把你的留言文字放进了报文 body 里,然后拼接好 POST 请求头,通过 TCP 协议发送给服务器。

    c8d63f4d30be8705c98e9ce02ac98ee6.png

    POST 请求

    GET 和 POST 方法都是安全和幂等的吗?

    先说明下安全和幂等的概念:

    • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
    • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

    那么很明显 GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。

    POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。


    03 HTTP 特性

    你知道的 HTTP(1.1) 的优点有哪些,怎么体现的?

    HTTP 最凸出的优点是「简单、灵活和易于扩展、应用广泛和跨平台」。

    1. 简单

    HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解,降低了学习和使用的门槛。

    2. 灵活和易于扩展

    HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充

    同时 HTTP 由于是工作在应用层( OSI 第七层),则它下层可以随意变化

    HTTPS 也就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层,HTTP/3 甚至把 TCPP 层换成了基于 UDP 的 QUIC。

    3. 应用广泛和跨平台

    互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用片地开花,同时天然具有跨平台的优越性。

    那它的缺点呢?

    HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」。

    1. 无状态双刃剑

    无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

    无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。

    例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

    这样每操作一次,都要验证信息,这样的购物体验还能愉快吗?别问,问就是酸爽

    对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。

    Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

    相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了

    bad0765693aa21b460f1cf2609a13e25.png

    Cookie 技术

    2. 明文传输双刃剑

    明文意味着在传输过程中的信息,是可方便阅读的,通过浏览器的 F12 控制台或 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。

    但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取,如果里面有你的账号密码信息,那你号没了

    169f55e663a9ad7acc398f5856a4b56b.png

    3. 不安全

    HTTP 比较严重的缺点就是不安全:

    • 通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了。
    • 不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了。
    • 无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了。

    HTTP 的安全问题,可以用 HTTPS 的方式解决,也就是通过引入 SSL/TLS 层,使得在安全上达到了极致。

    那你说下 HTTP/1.1 的性能如何?

    HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。

    1. 长连接

    早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无畏的 TCP 连接建立和断开,增加了通信开销。

    为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。

    持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

    3be648d621ef5e41efc94d53e2875696.png

    短连接与长连接

    2. 管道网络传输

    HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。

    即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

    举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求。

    6ae2f38a201e1bde298567afe0ba19c7.png

    管道网络传输

    但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」。

    3. 队头阻塞

    「请求 - 应答」的模式加剧了 HTTP 的性能问题。

    因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」。好比上班的路上塞车

    523b14f433bca90dc71fd637c9e34ee4.png

    队头阻塞

    总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。


    04 HTTP 与 HTTPS

    HTTP 与 HTTPS 有哪些区别?

    1. HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
    2. HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
    3. HTTP 的端口号是 80,HTTPS 的端口号是 443。
    4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

    HTTPS 解决了 HTTP 的哪些问题?

    HTTP 由于是明文传输,所以安全上存在以下三个风险:

    • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
    • 篡改风险,比如强制入垃圾广告,视觉污染,用户眼容易瞎。
    • 冒充风险,比如冒充淘宝网站,用户钱容易没。

    HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议。

    dbd3ca54b19468db1a2441f25d437128.png

    HTTP 与 HTTPS

    可以很好的解决了上述的风险:

    • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
    • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
    • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

    可见,只要自身不做「恶」,SSL/TLS 协议是能保证通信是安全的。

    HTTPS 是如何解决上面的三个风险的?

    • 混合加密的方式实现信息的机密性,解决了窃听的风险。
    • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
    • 将服务器公钥放入到数字证书中,解决了冒充的风险。

    1. 混合加密

    通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

    6046fff947f0eb9033be699a29bf5ef8.png

    混合加密

    HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

    • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
    • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

    采用「混合加密」的方式的原因:

    • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
    • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

    2. 摘要算法

    摘要算法用来实现完整性,能够为数据生成独一无二的「指纹」,用于校验数据的完整性,解决了篡改的风险。

    9f38d3cdcff8c05cdeda42c4d1bca1f7.png

    校验完整性

    客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。

    3. 数字证书

    客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

    这就存在些问题,如何保证公钥不被篡改和信任度?

    所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

    c994e42734e0d970de7fc7247b9ae4b7.png

    数字证书工作流程

    通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。

    HTTPS 是如何建立连接的?其间交互了什么?

    SSL/TLS 协议基本流程:

    • 客户端向服务器索要并验证服务器的公钥。
    • 双方协商生产「会话秘钥」。
    • 双方采用「会话秘钥」进行加密通信。

    前两步也就是 SSL/TLS 的建立过程,也就是握手阶段。

    SSL/TLS 的「握手阶段」涉及四次通信,可见下图:

    b73c5728ed649cdc5d2c577082999b02.png

    HTTPS 连接建立过程

    SSL/TLS 协议建立的详细流程:

    1. ClientHello

    首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。

    在这一步,客户端主要向服务器发送以下信息:

    (1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。

    (2)客户端生产的随机数(Client Random),后面用于生产「会话秘钥」。

    (3)客户端支持的密码套件列表,如 RSA 加密算法。

    2. SeverHello

    服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:

    (1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。

    (2)服务器生产的随机数(Server Random),后面用于生产「会话秘钥」。

    (3)确认的密码套件列表,如 RSA 加密算法。

    (4)服务器的数字证书。

    3.客户端回应

    客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。

    如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

    (1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。

    (2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

    (3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。

    上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。

    4. 服务器的最后回应

    服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息:

    (1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

    (2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

    至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。


    05 HTTP/1.1、HTTP/2、HTTP/3 演变

    说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

    HTTP/1.1 相比 HTTP/1.0 性能上的改进:

    • 使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
    • 支持 管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

    但 HTTP/1.1 还是有性能瓶颈:

    • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩Body 的部分;
    • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
    • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
    • 没有请求优先级控制;
    • 请求只能从客户端开始,服务器只能被动响应。

    那上面的 HTTP/1.1 的性能瓶颈,HTTP/2 做了什么优化?

    HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。

    那 HTTP/2 相比 HTTP/1.1 性能上的改进:

    1. 头部压缩

    HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分

    这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

    2. 二进制格式

    HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式。

    头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧

    bd05ce0d8f0aae1ee2f9cd434ef9dafa.png

    报文区别

    这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率

    3. 数据流

    HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。

    每个请求或回应的所有数据包,称为一个数据流(Stream)。

    每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数

    客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。

    8df4d6908a31de83b2fef9fa3fca5c9d.png

    HTT/1 ~ HTTP/2

    4. 多路复用

    HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应

    移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率

    举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分。

    4bad50dfda4ad8904f59c0124ccfecbd.png

    多路复用

    5. 服务器推送

    HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。

    举例来说,在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。

    HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?

    HTTP/2 主要的问题在于:多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。

    所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

    • HTTP/1.1 中的管道( pipeline)传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了
    • HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。

    这都是基于 TCP 传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

    9dc58dd449c6d336717a842c2bd61fae.png

    HTTP/1 ~ HTTP/3

    UDP 发生是不管顺序,也不管丢包的,所以不会出现 HTTP/1.1 的队头阻塞 和 HTTP/2 的一个丢包全部重传问题。

    大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

    • QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响
    • TL3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPack。
    • HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数
    be6623c4e21c3a459f8abf0579e1cba2.png

    TCP HTTPS(TLS/1.3) 和 QUIC HTTPS

    所以, QUIC 是一个在 UDP 之上的 TCP + TLS + HTTP/2 的多路复用的协议。

    QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。

    展开全文
  • Linux网络编程——无连接和面向连接协议的区别

    万次阅读 多人点赞 2015-03-19 15:26:25
    网络编程中最基本的概念...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢?答案是:面向连接和无连接指的都是协议。也就是说,这些...

    网络编程中最基本的概念就是面向连接(connection-oriented)和无连接(connectionless)协议。尽管本质上来说,两者之间的区别并不难理解,但对那些刚刚开始进行网络编程的人来说,却是个很容易混淆的问题。这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢?


    答案是:面向连接和无连接指的都是协议。也就是说,这些术语指的并不是物理介质本身,而是用来说明如何在物理介质上传输数据的。面向连接和无连接协议可以,而且通常也确实会共享同一条物理介质。

    如果两者的区别与承载数据的物理介质无关,又和什么有关呢?它们的本质区别在于,对无连接协议来说,每个分组的处理都独立于所有其他分组,而对面向连接的协议来说,协议实现则维护了与后继分组有关的状态信息。


    无连接协议中的分组被称为数据报(datagram),每个分组都是独立寻址,并由应用程序发送的。从协议的角度来看,每个数据报都是一个独立的实体,与在两个相同的对等实体之间传送的任何其他数据报都没有关系,这就意味着协议很可能是不可靠的。也就是说,网络会尽最大努力传送每一个数据报,但并不保证数据报不丢失、不延迟或者不错序传输。


    另一方面,面向连接的协议则维护了分组之间的状态,使用这种协议的应用程序通常都会进行长期的对话。记住这些状态,协议就可以提供可靠的传输。比如,发送端可以记住哪些数据已经发送出去了但还未被确认,以及数据是什么时候发送的。如果在某段时间间隔内没有收到确认,发送端可以重传数据。接收端可以记住已经收到了哪些数据,并将重复的数据丢弃。如果分组不是按序到达的,接收端可以将其保存下来,直到逻辑上先于它的分组到达为止。


    典型的面向连接协议有三个阶段。第一阶段,在对等实体间建立连接。接下来是数据传输阶段,在这个阶段中,数据在对等实体间传输。最后,当对等实体完成数据传输时,连接被拆除。


    一种标准的类比是:使用无连接协议就像寄信,而使用面向连接的协议就像打电话。


    给朋友寄信时,每封信都是一个独立寻址且自包含的实体。邮局在处理这些信件时不会考虑到两个通信者之间的任何其他信件。邮局不会维护以往通信者的历史记录--也就是说,它不会维护信件之间的状态。邮局也不保证信件不丢失、不延迟、不错序。这种方式就对应于无连接协议发送数据报的方式。(用明信片进行类比会更合适一些,因为写错地址的信件会被退回发信人,而(和典型的无连接协议数据报一样)明信片则不会。)


    现在来看看不是给朋友寄信,而是打电话时会发生些什么事情。


    首先,拨朋友的号码来发起呼叫。朋友应答,会说“嗨”之类的话,然后我们回应:“嗨,Lucy。我是 Mike。”我们和朋友聊一会儿,然后互说再见并挂机。这是面向连接协议中发生的典型状况。在连接建立阶段,一端与其对等实体联系,交换初始问候信息,对会话中要用到的一些参数和选项进行沟通,然后连接进入数据传输阶段。

    在电话交谈的过程中,两端用户都知道他们在和谁说话,因此没必要不停地说“这是 Mike 在跟 Lucy 说话”。也没必要在每次说话之前都拨一次朋友的电话号码——我们的电话已经连接起来了。同理,在面向连接协议的数据传输阶段,也没必要说明我们自己或对等实体的地址。连接为我们维护的状态中包含了这些地址。我们只要发送数据就行了,不需要考虑寻址或其他与协议相关的问题。

    就像用电话交谈一样,连接的任一端完成数据的传输时,都要通知其对等实体。两端都完成传输时,要依次将连接拆除。


    既然无连接协议有这么多的缺点,大家可能会奇怪,为什么还要使用这种协议呢?我们会看到,在很多情况下,使用无连接协议构建应用程序都是有意义的。比如,使用无连接协议可以很方便地支持一对多和多对一通信,而面向连接协议通常都需要多个独立的连接才能做到。但更重要的是,无连接协议是构建面向连接协议的基础。TCP/IP 是基于一个4层的协议栈,如下图所示:


    如图所示,TCP 和 UDP 都是构建在 IP 之上的。因此,IP 是构建整个 TCP/IP 协议族的基础。但 IP 提供的是一种尽力而为的、不可靠的无连接服务。它接收来自其上层的分组,将它们封装在一个 IP 分组中,根据路由为分组选择正确的硬件接口,从这个接口将分组发送出去。一旦将分组发送出去了,IP 就不再关心这个分组了。和所有无连接协议一样,它将分组发送出去之后就不再记得这个分组了。


    这种简单性也是 IP 的主要优点。因为它对底层的物理介质没有作任何假设,所以在任何能够承载分组的物理链路上都可以运行 IP。例如,IP 可以运行在简单的串行链路、以太网和令牌环 LAN、X.25 和使用 ATM(Asychronous Transfer Mode,异步转移模式)的 WAN、CDPD(Cellular Digital Packet Data,无线蜂窝数字分组数据)网,以及很多其他网络上。尽管这些网络技术之间有很大的差异,但 IP 对它们一视同仁,除了认为它们可以转发分组之外没有对其作任何假设。这种机制隐含了很深的意义。IP 可以运行在任何能够承载分组的网络上,所以整个 TCP/IP 协议族也可以。


    现在我们来看看 TCP 是怎样利用这种简单的无连接服务来提供可靠的面向连接服务的。TCP 的分组被称为段(segment),是放在 IP 数据报中发送的,因此,根本无法假定这些分组会抵达目的地,更不用说保证分组无损坏且以原来的顺序到达了。


    为了提供这种可靠性,TCP 向基本的 IP 服务中添加了三项功能
    首先,它为 TCP 段中的数据提供了校验和。这样有助于确保抵达目的地的数据在传输过程中不会被网络损坏。
    第二,它为每字节分配了一个序列号,这样,如果数据抵达目的地时真的错序了,接收端也能够按照恰当的顺序将其重装起来。当然,TCP 并没有为每字节都附加一个序列号。实际上,每个 TCP 段的首部都包含了段中第一字节的序列号。这样,就隐含地知道了段中其他字节的序列号。
    第三,TCP 提供了一种确认-重传机制,以确保最终每个段都会被传送出去。


    另一方面,UDP 为编写应用程序的程序员提供了一种不可靠的无连接服务。事实上,UDP 只向底层的 IP 协议中添加了两项功能。

    首先,它提供了一个可选的校验和来检测数据的损坏情况。尽管 IP 也有校验和,但它只对 IP 分组首部进行计算,所以,TCP 和 UDP 也都提供了校验和来保护它们自己的首部和数据。

    其次,UDP 向 IP添加的第二项特性就是端口的概念。


    回到与电话/寄信的类比中来,我们可以把 TCP 连接中的网络地址当作一个办公室总机的电话号码,把端口号当作办公室中某台正被呼叫的特定电话的分机号。同理,可以将UDP网络地址当作一座公寓楼的地址,并把端口号当作公寓楼大厅中的个人邮箱。



    展开全文
  • 这里搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。应该说HTTP和HTTPS部分的面试题,看...

    前言

    在面试过程中,HTTP 被提问的概率还是比较高的。

    这里搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。

    应该说HTTP和HTTPS部分的面试题,看这些基本就够了。

    1. HTTP 基本概念
    2. Get 与 Post
    3. HTTP 特性
    4. HTTPS 与 HTTP
    5. HTTP/1.1、HTTP/2、HTTP/3 演变

    ff4eb2d009d9df4724a49d810097f869.png

    正文

    01 HTTP 基本概念

    HTTP 是什么?描述一下

    HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。

    能否详细解释「超文本传输协议」?

    HTTP的名字「超文本协议传输」,它可以拆成三个部分:

    • 超文本
    • 传输
    • 协议

    fddcebf88606610ab8934e0c85e83778.png

    三个部分

    1. 「协议」

    在生活中,我们也能随处可见「协议」,例如:

    • 刚毕业时会签一个「三方协议」;
    • 找房子时会签一个「租房协议」;

    6471524fb0d793d12520bf247c8c467e.png

    三方协议和租房协议

    生活中的协议,本质上与计算机中的协议是相同的,协议的特点:

    • 」字,代表的意思是必须有两个以上的参与者。例如三方协议里的参与者有三个:你、公司、学校三个;租房协议里的参与者有两个:你和房东。
    • 」字,代表的意思是对参与者的一种行为约定和规范。例如三方协议里规定试用期期限、毁约金等;租房协议里规定租期期限、每月租金金额、违约如何处理等。

    针对 HTTP 协议,我们可以这么理解。

    HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范(两个以上的参与者),以及相关的各种控制和错误处理方式(行为约定和规范)。

    2. 「传输」

    所谓的「传输」,很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点 搬到 A 点。

    别轻视了这个简单的动作,它至少包含两项重要的信息。

    HTTP 协议是一个双向协议

    我们在上网冲浪时,浏览器是请求方 A ,百度网站就是应答方 B。双方约定用 HTTP 协议来通信,于是浏览器把请求数据发送给网站,网站再把一些数据返回给浏览器,最后由浏览器渲染在屏幕,就可以看到图片、视频了。

    6f766113a01c14ed0fb7061bf5b804ea.png

    请求 - 应答

    数据虽然是在 A 和 B 之间传输,但允许中间有中转或接力

    就好像第一排的同学想穿递纸条给最后一排的同学,那么传递的过程中就需要经过好多个同学(中间人),这样的传输方式就从「A < --- > B」,变成了「A <-> N <-> M <-> B」。

    而在 HTTP 里,需要中间人遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意额外的东西。

    针对传输,我们可以进一步理解了 HTTP。

    HTTP 是一个在计算机世界里专门用来在两点之间传输数据的约定和规范。

    3. 「超文本」

    HTTP 传输的内容是「超文本」。

    我们先来理解「文本」,在互联网早期的时候只是简单的字符文字,但现在「文本」。的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算做「文本」。

    再来理解「超文本」,它就是超越了普通文本的文本,它是文字、图片、视频等的混合体最关键有超链接,能从一个超文本跳转到另外一个超文本。

    HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解释,呈现给我们的就是一个文字、有画面的网页了。

    OK,经过了对 HTTP 里这三个名词的详细解释,就可以给出比「超文本传输协议」这七个字更准确更有技术含量的答案:

    HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」。

    那「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议HTTP」 ,这种说法正确吗?

    这种说法是不正确的。因为也可以是「服务器< -- >服务器」,所以采用两点之间的描述会更准确。

    HTTP 常见的状态码,有哪些?

    70add791e1abb6947b847a2000694dcc.png

    五大类 HTTP 状态码

    1xx

    1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。

    2xx

    2xx 类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。

    200 OK」是最常见的成功状态码,表示一切正常。如果是非 HEAD 请求,服务器返回的响应头都会有 body 数据。

    204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。

    206 Partial Content」是应用于 HTTP 分块下载或断电续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。

    3xx

    3xx 类状态码表示客户端请求的资源发送了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向

    301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。

    302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。

    301 和 302 都会在响应头里使用字段 Location,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。

    304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。

    4xx

    4xx 类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。

    400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。

    403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。

    404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。

    5xx

    5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

    500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。

    501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。

    502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。

    503 Service Unavailable」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。

    http 常见字段有哪些?

    Host

    客户端发送请求时,用来指定服务器的域名。

    40f8b0af228e7366ebe0f1ccde4aa362.png
    Host: www.A.com

    有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站。

    Content-Length 字段

    服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度。

    221c9b6a89c428ca796b731373f0aa7c.png
    Content-Length: 1000

    如上面则是告诉浏览器,本次服务器回应的数据长度是 1000 个字节,后面的字节就属于下一个回应了。

    Connection 字段

    Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。

    e28083fd7df07031868d192ccf535cc5.png

    HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive。

    Connection: keep-alive

    一个可以复用的 TCP 连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段。

    Content-Type 字段

    Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。

    6cece3f1d0c620f796b310238948b71d.png
    Content-Type: text/html; charset=utf-8

    上面的类型表明,发送的是网页,而且编码是UTF-8。

    客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。

    Accept: */*

    上面代码中,客户端声明自己可以接受任何格式的数据。

    Content-Encoding 字段

    Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式

    ab77398b9a3f0409a0b81bf24324f8e2.png
    Content-Encoding: gzip

    上面表示服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。

    客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。

    Accept-Encoding: gzip, deflate

    GET 与 POST

    说一下 GET 和 POST 的区别?

    Get 方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。

    比如,你打开我的文章,浏览器就会发送 GET 请求给服务器,服务器就会返回文章的所有文字及资源。

    f09589b92e949f92512da2604b45bc5e.png

    GET 请求

    而POST 方法则是相反操作,它向 URI 指定的资源提交数据,数据就放在报文的 body 里。

    比如,你在我文章底部,敲入了留言后点击「提交」(暗示你们留言),浏览器就会执行一次 POST 请求,把你的留言文字放进了报文 body 里,然后拼接好 POST 请求头,通过 TCP 协议发送给服务器。

    0df78f04056c8bf0b6101cf443f76d6d.png

    POST 请求

    GET 和 POST 方法都是安全和幂等的吗?

    先说明下安全和幂等的概念:

    • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
    • 所谓的「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

    那么很明显 GET 方法就是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。

    POST 因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。


    03 HTTP 特性

    你知道的 HTTP(1.1) 的优点有哪些,怎么体现的?

    HTTP 最凸出的优点是「简单、灵活和易于扩展、应用广泛和跨平台」。

    1. 简单

    HTTP 基本的报文格式就是 header + body,头部信息也是 key-value 简单文本的形式,易于理解,降低了学习和使用的门槛。

    2. 灵活和易于扩展

    HTTP协议里的各类请求方法、URI/URL、状态码、头字段等每个组成要求都没有被固定死,都允许开发人员自定义和扩充

    同时 HTTP 由于是工作在应用层( OSI 第七层),则它下层可以随意变化

    HTTPS 也就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层,HTTP/3 甚至把 TCPP 层换成了基于 UDP 的 QUIC。

    3. 应用广泛和跨平台

    互联网发展至今,HTTP 的应用范围非常的广泛,从台式机的浏览器到手机上的各种 APP,从看新闻、刷贴吧到购物、理财、吃鸡,HTTP 的应用片地开花,同时天然具有跨平台的优越性。

    那它的缺点呢?

    HTTP 协议里有优缺点一体的双刃剑,分别是「无状态、明文传输」,同时还有一大缺点「不安全」。

    1. 无状态双刃剑

    无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

    无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。

    例如登录->添加购物车->下单->结算->支付,这系列操作都要知道用户的身份才行。但服务器不知道这些请求是有关联的,每次都要问一遍身份信息。

    这样每操作一次,都要验证信息,这样的购物体验还能愉快吗?别问,问就是酸爽

    对于无状态的问题,解法方案有很多种,其中比较简单的方式用 Cookie 技术。

    Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

    相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了了

    de9715257982da1208470d55d1bc2f88.png

    Cookie 技术

    2. 明文传输双刃剑

    明文意味着在传输过程中的信息,是可方便阅读的,通过浏览器的 F12 控制台或 Wireshark 抓包都可以直接肉眼查看,为我们调试工作带了极大的便利性。

    但是这正是这样,HTTP 的所有信息都暴露在了光天化日下,相当于信息裸奔。在传输的漫长的过程中,信息的内容都毫无隐私可言,很容易就能被窃取,如果里面有你的账号密码信息,那你号没了

    bc8272b1dde4d599a050cefb54c9447f.png

    3. 不安全

    HTTP 比较严重的缺点就是不安全:

    • 通信使用明文(不加密),内容可能会被窃听。比如,账号信息容易泄漏,那你号没了。
    • 不验证通信方的身份,因此有可能遭遇伪装。比如,访问假的淘宝、拼多多,那你钱没了。
    • 无法证明报文的完整性,所以有可能已遭篡改。比如,网页上植入垃圾广告,视觉污染,眼没了。

    HTTP 的安全问题,可以用 HTTPS 的方式解决,也就是通过引入 SSL/TLS 层,使得在安全上达到了极致。

    那你说下 HTTP/1.1 的性能如何?

    HTTP 协议是基于 TCP/IP,并且使用了「请求 - 应答」的通信模式,所以性能的关键就在这两点里。

    1. 长连接

    早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无畏的 TCP 连接建立和断开,增加了通信开销。

    为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。

    持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

    226c1b56ebe735f4186443e605217752.png

    短连接与长连接

    2. 管道网络传输

    HTTP/1.1 采用了长连接的方式,这使得管道(pipeline)网络传输成为了可能。

    即可在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

    举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求。

    56681cda48334692950c53ac117e2bdd.png

    管道网络传输

    但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。要是 前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」。

    3. 队头阻塞

    「请求 - 应答」的模式加剧了 HTTP 的性能问题。

    因为当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一同被阻塞了,会招致客户端一直请求不到数据,这也就是「队头阻塞」。好比上班的路上塞车

    f54ac50e41c7036350891d371a0c1790.png

    队头阻塞

    总之 HTTP/1.1 的性能一般般,后续的 HTTP/2 和 HTTP/3 就是在优化 HTTP 的性能。


    04 HTTP 与 HTTPS

    HTTP 与 HTTPS 有哪些区别?
    1. HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
    2. HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
    3. HTTP 的端口号是 80,HTTPS 的端口号是 443。
    4. HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
    HTTPS 解决了 HTTP 的哪些问题?

    HTTP 由于是明文传输,所以安全上存在以下三个风险:

    • 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
    • 篡改风险,比如强制入垃圾广告,视觉污染,用户眼容易瞎。
    • 冒充风险,比如冒充淘宝网站,用户钱容易没。

    HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议。

    26d164c75f373bef54e21d7eed3f6b89.png

    HTTP 与 HTTPS

    可以很好的解决了上述的风险:

    • 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
    • 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
    • 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。

    可见,只要自身不做「恶」,SSL/TLS 协议是能保证通信是安全的。

    HTTPS 是如何解决上面的三个风险的?
    • 混合加密的方式实现信息的机密性,解决了窃听的风险。
    • 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险。
    • 将服务器公钥放入到数字证书中,解决了冒充的风险。

    1. 混合加密

    通过混合加密的方式可以保证信息的机密性,解决了窃听的风险。

    3d8328f85f480b775befd317ec62e01e.png

    混合加密

    HTTPS 采用的是对称加密非对称加密结合的「混合加密」方式:

    • 在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密。
    • 在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。

    采用「混合加密」的方式的原因:

    • 对称加密只使用一个密钥,运算速度快,密钥必须保密,无法做到安全的密钥交换。
    • 非对称加密使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,解决了密钥交换问题但速度慢。

    2. 摘要算法

    摘要算法用来实现完整性,能够为数据生成独一无二的「指纹」,用于校验数据的完整性,解决了篡改的风险。

    f8ff29eb34b86cdcefc6f7ac06d24830.png

    校验完整性

    客户端在发送明文之前会通过摘要算法算出明文的「指纹」,发送的时候把「指纹 + 明文」一同加密成密文后,发送给服务器,服务器解密后,用相同的摘要算法算出发送过来的明文,通过比较客户端携带的「指纹」和当前算出的「指纹」做比较,若「指纹」相同,说明数据是完整的。

    3. 数字证书

    客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

    这就存在些问题,如何保证公钥不被篡改和信任度?

    所以这里就需要借助第三方权威机构 CA (数字证书认证机构),将服务器公钥放在数字证书(由数字证书认证机构颁发)中,只要证书是可信的,公钥就是可信的。

    c96b5645f22c37441c9531e1f79873cb.png

    数字证书工作流程

    通过数字证书的方式保证服务器公钥的身份,解决冒充的风险。

    HTTPS 是如何建立连接的?其间交互了什么?

    SSL/TLS 协议基本流程:

    • 客户端向服务器索要并验证服务器的公钥。
    • 双方协商生产「会话秘钥」。
    • 双方采用「会话秘钥」进行加密通信。

    前两步也就是 SSL/TLS 的建立过程,也就是握手阶段。

    SSL/TLS 的「握手阶段」涉及四次通信,可见下图:

    b5fc2e94070c7ef2fc73f23562594487.png

    HTTPS 连接建立过程

    SSL/TLS 协议建立的详细流程:

    1. ClientHello

    首先,由客户端向服务器发起加密通信请求,也就是 ClientHello 请求。

    在这一步,客户端主要向服务器发送以下信息:

    (1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。

    (2)客户端生产的随机数(Client Random),后面用于生产「会话秘钥」。

    (3)客户端支持的密码套件列表,如 RSA 加密算法。

    2. SeverHello

    服务器收到客户端请求后,向客户端发出响应,也就是 SeverHello。服务器回应的内容有如下内容:

    (1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。

    (2)服务器生产的随机数(Server Random),后面用于生产「会话秘钥」。

    (3)确认的密码套件列表,如 RSA 加密算法。

    (4)服务器的数字证书。

    3.客户端回应

    客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。

    如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:

    (1)一个随机数(pre-master key)。该随机数会被服务器公钥加密。

    (2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

    (3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。

    上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。

    4. 服务器的最后回应

    服务器收到客户端的第三个随机数(pre-master key)之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息:

    (1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。

    (2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。

    至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。


    05 HTTP/1.1、HTTP/2、HTTP/3 演变

    说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能?

    HTTP/1.1 相比 HTTP/1.0 性能上的改进:

    • 使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。
    • 支持 管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。

    但 HTTP/1.1 还是有性能瓶颈:

    • 请求 / 响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分;
    • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
    • 服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞;
    • 没有请求优先级控制;
    • 请求只能从客户端开始,服务器只能被动响应。
    那上面的 HTTP/1.1 的性能瓶颈,HTTP/2 做了什么优化?

    HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的。

    那 HTTP/2 相比 HTTP/1.1 性能上的改进:

    1. 头部压缩

    HTTP/2 会压缩头(Header)如果你同时发出多个请求,他们的头是一样的或是相似的,那么,协议会帮你消除重复的分

    这就是所谓的 HPACK 算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。

    2. 二进制格式

    HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用了二进制格式。

    头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧

    d135212be809a746300c7b5d98352c92.png

    报文区别

    这样虽然对人不友好,但是对计算机非常友好,因为计算机只懂二进制,那么收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率

    3. 数据流

    HTTP/2 的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。

    每个请求或回应的所有数据包,称为一个数据流(Stream)。

    每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数

    客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。

    5e5120492a1b45481f0cd6f6f37c744e.png

    HTT/1 ~ HTTP/2

    4. 多路复用

    HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应

    移除了 HTTP/1.1 中的串行请求,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率

    举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分。

    0f9325c8faaa3c2b46f0e33a5d804aa6.png

    多路复用

    5. 服务器推送

    HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。

    举例来说,在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫 Cache Push)。

    HTTP/2 有哪些缺陷?HTTP/3 做了哪些优化?

    HTTP/2 主要的问题在于:多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。

    所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来

    • HTTP/1.1 中的管道( pipeline)传输中如果有一个请求阻塞了,那么队列后请求也统统被阻塞住了
    • HTTP/2 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。

    这都是基于 TCP 传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

    b314cce6f042a79f05898bb3f6b3f672.png

    HTTP/1 ~ HTTP/3

    UDP 发生是不管顺序,也不管丢包的,所以不会出现 HTTP/1.1 的队头阻塞 和 HTTP/2 的一个丢包全部重传问题。

    大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输。

    • QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响
    • TL3 升级成了最新的 1.3 版本,头部压缩算法也升级成了 QPack。
    • HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是 TLS/1.3 的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互合并成了 3 次,减少了交互次数

    e239927978adbf6254f0644370a794c2.png

    TCP HTTPS(TLS/1.3) 和 QUIC HTTPS

    所以, QUIC 是一个在 UDP 之上的 TCP + TLS + HTTP/2 的多路复用的协议。

    QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,这样会出现新的问题。所以 HTTP/3 现在普及的进度非常的缓慢,不知道未来 UDP 是否能够逆袭 TCP。

    看完觉得不错可以关注一下小编,后续还会持续更新干货文章!!

    展开全文
  • 网络编程中最基本的概念就是面向连接...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢? 答案是:面向连接和无连接指的都是
  • 网络编程中最基本的概念就是...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢? 答案是:面向连接和无连接指的都是协议。也就...
  • 从字面的意思上来说是协议意思,那么到底什么协议呢?那我们来普及一下协议的概念。 协议的概念 (1)协议相当于没有与类相关联的接口,他申明一组方法,列出他的参数和返回值,共享给其他类使用,然后不进行...
  • 无连接和面向连接协议的区别

    万次阅读 多人点赞 2018-10-15 16:01:26
      网络编程中最基本的概念...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢?   答案是:面向连接和无连接指的都是协议。也就...
  • 但这到底是什么意思?谁决定协议属于哪个层? OSI模型最初是在1970年代构思的,是OSI协议套件的组成部分,该套件被定位为新兴TCP / IP协议家族的早期竞争者(破坏者警报:TCP / IP获胜)。幸存者(最著名
  • 网络编程中最基本的概念...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢?答案是:面向连接和无连接指的都是协议。也就是说,这些...
  • 网络编程中最重要的概念就是连接取向(connection-oriented)和无连接(connectionless)协议。...那“无连接通信”又是什么意思呢? 答案是:面向连接和无连接指的都是协议。也就是说,这些术...
  • 什么是3C融合

    2008-10-16 16:18:00
    3C融合(3c fusion)是什么意思?3C融合(3c fusion)是指计算机(Computer)、通讯(Communication)和消费类电子产品(Consumer Electrics),3C融合便是利用数字信息技术激活其中任何一个环节,通过某种协议使3C的三个...
  • 无状态的意思是,第一次发送请求登录成功后,第二次发送请求其他接口,服务端是不知道你已经登录成功,第二次请求和第一次请求是没有任何关联的. Http的这个特性就产生了一个问题,导致登录状态的丢失.于是在每次请求的...
  • 总结 Session Hijacking

    2018-08-13 10:28:19
    这句话里的无状态是什么意思 http协议添加了cookie,使http可以变得有状态,通过发送请求时带上cookie,服务器端返回设置cookie。 session就是依托cookie机制建立的用户回话机制。 sessionId是sess...
  • 读Linux内核(4.9.9)之bind系统调用

    千次阅读 2016-03-23 22:05:00
    那这个绑定到底是个什么意思?这个绑定操作是必须吗?绑定操作之后,socket对象又发生了什么?也许还有更多的疑问,我们在协议栈的源码寻找答案。先贴上bind系统调用的源码:/* * Bind a name to a sock...
  • 学习过OC的都应该知道,在OC中有一个单词 “Mutable”,它的意思是可变的。 那什么是可变,什么是不可变呢? 首先先了解一下什么是Foundation框架 Foundation框架是IOS/MAC中其他框架的基础,Foundation类层次...
  • 网络编程中最基本的概念就是面向连接...这个问题与上下文有些关联:很显然,如果两台计算机要进行通信,就必须以某种形式“连接”起来,那“无连接通信”又是什么意思呢? 答案是:面向连接和无连接指的都是
  • 通过定义几类相互关联的探测点和库函数,来收集和处理运行中内核的数据,以及修改内核的处理逻辑。  为什么要基于systemtap呢?systemtap的神奇之处在于,不修改内核的情况下就能获取内核中的任何信息, 还可以...
  • java-servlet-api.doc

    2009-10-13 19:34:17
    加入的意思是返回会话跟踪信息到服务器中,指出会话已被建立。在客户端加入之前,我们不能判断下一个客户端请求是目前会话的一部分。 在下面的情况下,Session会被认为是新的Session。 客户端的Session在此之前还不...
  • 当客户机第一次调用一个Stateful Session Bean 时,容器必须立即在服务器中创建一个新的Bean实例,并关联到客户机上,以后此客户机调用Stateful Session Bean 的方法时容器会把调用分派到与此客户机相关联的Bean实例...
  • java 面试题 总结

    2009-09-16 08:45:34
     GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收...

空空如也

空空如也

1 2
收藏数 39
精华内容 15
关键字:

关联协议什么意思