前言
由于对客户端的开发非常感兴趣,所以不仅准备找后端的工作岗位也准备找客户端的岗位,客户端这边看很多面经上对 http 和https非常重视,今天特意总结一下。之所以叫泛谈,因为是写一个大概的http和https的请求过程,大概的区别,并不详细介绍。我在博客上看到一个大佬的总结非常之详细,思路非常之清晰,后面借助这位大佬的总结,去详细说一下http和https的各个方面。
HTTP和HTTPS
HTTP 是一种 超文本传输协议 (Hypertext Transfer Protocol),HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。
说到 HTTP,不得不提的就是 TCP/IP 网络模型,一般是五层模型。如下图所示:
但是也可以分为四层,就是把 链路层和物理层都表示为网络接口层:
还有一种就是 OSI 七层网络模型,它就是在五层协议之上加了表示层和会话层
而 HTTPS 的全称是 Hypertext Transfer Protocol Secure
,从名称我们可以看出 HTTPS 要比 HTTPS 多了 secure 安全性这个概念,实际上, HTTPS 并不是一个新的应用层协议,它其实就是 HTTP + TLS/SSL 协议组合而成,而安全性的保证正是 TLS/SSL 所做的工作。也就是说,HTTPS 就是身披了一层 SSL 的 HTTP。
那么,HTTP 和 HTTPS 的主要区别是什么呢?
- 最简单的,HTTP 在地址栏上的协议是以
http://
开头,而 HTTPS 在地址栏上的协议是以https://
开头:
http://www.cxuanblog.com/
https://www.cxuanblog.com/
- HTTP 是未经安全加密的协议,它的传输过程容易被攻击者监听、数据容易被窃取、发送方和接收方容易被伪造;而 HTTPS 是安全的协议,它通过 密钥交换算法 - 签名算法 - 对称加密算法 - 摘要算法 能够解决上面这些问题。说到底还是建立在SSL之上。
- HTTP 的默认端口是
80
,而 HTTPS 的默认端口是443
。
什么是无状态协议,HTTP 是无状态协议吗,怎么解决
无状态协议(Stateless Protocol)
就是指浏览器对于事务的处理没有记忆能力。举个例子来说就是比如客户请求获得网页之后关闭浏览器,然后再次启动浏览器,登录该网站,但是服务器并不知道客户关闭了一次浏览器。
HTTP 就是一种无状态的协议,他对用户的操作没有记忆能力。可能大多数用户不相信,他可能觉得每次输入用户名和密码登陆一个网站后,下次登陆就不再重新输入用户名和密码了。这其实不是 HTTP 做的事情,起作用的是一个叫做 小甜饼(Cookie)
的机制。它能够让浏览器具有记忆能力
。
Cookie
当你向服务端发送请求时,服务端会给你发送一个认证信息,服务器第一次接收到请求时,开辟了一块 Session 空间(创建了Session对象),同时生成一个 sessionId ,并通过响应头的 Set-Cookie:JSESSIONID=XXXXXXX 命令,向客户端发送要求设置 Cookie 的响应;客户端收到响应后,在本机客户端
设置了一个 JSESSIONID=XXXXXXX 的 Cookie 信息,该 Cookie 的过期时间为浏览器会话结束;
接下来客户端每次向同一个网站发送请求时,请求头都会带上该 Cookie信息(包含 sessionId ), 然后,服务器通过读取请求头中的 Cookie 信息,获取名称为 JSESSIONID 的值,得到此次请求的 sessionId。这样,你的浏览器才具有了记忆能力。
简述 HTTP1.0/1.1/2.0 的区别
HTTP 1.0
- HTTP 1.0 仅仅提供了最基本的认证,这时候
用户名和密码还未经加密
,因此很容易收到窥探。 - HTTP 1.0 被设计用来使用
短链接
,即每次发送数据都会经过 TCP 的三次握手和四次挥手,效率比较低。 - HTTP 1.0 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
- HTTP 1.0 不支持断点续传,也就是说,每次都会传送
全部的页面和数据。
- HTTP 1.0 认为每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)。
HTTP 1.1
HTTP 1.1 是 HTTP 1.0 开发三年后出现的,也就是 1999 年,它做出了以下方面的变化
- HTTP 1.1 使用了
摘要算法
来进行身份验证 - HTTP 1.1 默认使用
长连接
,长连接就是只需一次建立就可以传输多次数据,传输完成后,只需要一次切断连接即可。长连接的连接时长可以通过请求头中的 keep-alive 来设置 - HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
- HTTP 1.1 支持
断点续传,
通过使用请求头中的 Range 来实现。 - HTTP 1.1 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
HTTP 2.0
HTTP 2.0 是 2015 年开发出来的标准,它主要做的改变如下:
头部压缩
,由于 HTTP 1.1 经常会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用HPACK 算法进行压缩
。二进制格式
,HTTP 2.0 使用了更加靠近 TCP/IP 的二进制格式,而抛弃了 ASCII 码,提升了解析效率。强化安全
,由于安全已经成为重中之重,所以 HTTP2.0 一般都跑在 HTTPS 上。多路复用
,即每一个请求都是是用作连接共享。一个请求对应一个id,这样一个连接上可以有多个请求。
地址栏输入 URL 发生了什么
这道题也是一道经常会考的面试题。那么下面我们就来探讨一下从你输入 URL 后到响应,都经历了哪些过程。
- 首先,你需要在浏览器中的 URL 地址上,输入你想访问的地址,如下:
你应该访问不到的,对不对~
- 然后,查询请求会先找到
本地 DNS
服务器来查询是否包含 IP 地址,如果本地 DNS 无法查询到目标 IP 地址,就会向根域名服务器发起一个 DNS 查询。
注意:DNS 涉及两种查询方式:
一种是递归查询(Recursive query)
,一种是迭代查询(Iteration query)
。
如果根域名服务器无法告知本地 DNS 服务器下一步需要访问哪个顶级域名服务器,就会使用递归查询;
如果根域名服务器能够告知 DNS 服务器下一步需要访问的顶级域名服务器,就会使用迭代查询。
在由根域名服务器 -> 顶级域名服务器 -> 权威 DNS 服务器后,由权威服务器告诉本地服务器目标 IP 地址,再有本地 DNS 服务器告诉用户需要访问的 IP 地址。
- 第三步,浏览器需要和目标服务器建立 TCP 连接,需要经过三次握手的过程.
- 在建立连接后,浏览器会向目标服务器发起 HTTP-GET 请求,包括其中的 URL,HTTP 1.1 后默认使用长连接,只需要一次握手即可多次传输数据。
- 如果目标服务器只是一个简单的页面,就会直接返回。但是对于某些大型网站的站点,往往不会直接返回主机名所在的页面,
而会直接重定向
。返回的状态码就不是 200 ,而是 301,302 以 3 开头的重定向码,浏览器在获取了重定向响应后,在响应报文中 Location 项找到重定向地址,浏览器重新第一步访问即可。 - 然后浏览器重新发送请求,携带
新的 URL
,返回状态码 200 OK,表示服务器可以响应请求,返回报文。
HTTPS 的工作原理
我们上面描述了一下 HTTP 的工作原理,下面来讲述一下 HTTPS 的工作原理。因为我们知道 HTTPS 不是一种新出现的协议,而是
所以,我们探讨 HTTPS 的握手过程,其实就是 SSL/TLS 的握手过程。
TLS 旨在为 Internet 提供通信安全的加密协议。TLS 握手是启动和使用 TLS 加密的通信会话的过程。在 TLS 握手期间,Internet 中的通信双方会彼此交换信息,验证密码套件,交换会话密钥。
每当用户通过 HTTPS 导航到具体的网站并发送请求时,就会进行 TLS 握手。除此之外,每当其他任何通信使用HTTPS(包括 API 调用和在 HTTPS 上查询 DNS)时,也会发生 TLS 握手。
TLS 具体的握手过程会根据所使用的密钥交换算法的类型和双方支持的密码套件而不同。 我们以RSA 非对称加密
来讨论这个过程。整个 TLS 通信流程图如下:
- 在进行通信前,首先会进行 HTTP 的
三次握手
,握手完成后,再进行 TLS 的握手过程 - ClientHello:客户端通过向服务器发送
hello
消息来发起握手过程。这个消息中会夹带着客户端支持的 TLS 版本号(TLS1.0 、TLS1.2、TLS1.3) 、客户端支持的密码套件、以及一串客户端随机数。 - ServerHello:在客户端发送 hello 消息后,
服务器
会发送一条消息,这条消息包含了服务器的 SSL 证书、服务器选择的密码套件和服务器生成的随机数。 - 认证(Authentication):客户端的证书颁发机构会认证 SSL 证书,然后发送
Certificate 报文
,报文中包含公开密钥证书。最后服务器发送ServerHelloDone
作为 hello 请求的响应。第一部分握手阶段结束。 - 加密阶段:在第一个阶段握手完成后,客户端会发送
ClientKeyExchange
作为响应,这个响应中包含了一种称为 The premaster secret 的密钥字符串,这个字符串就是使用上面公开密钥证书进行加密的字符串。随后客户端会发送ChangeCipherSpec
,告诉服务端使用私钥解密这个 premaster secret 的字符串,然后客户端发送Finished
告诉服务端自己发送完成了。 - 实现了安全的非对称加密:然后,服务器再发送
ChangeCipherSpec
和Finished
告诉客户端解密完成,至此实现了 RSA 的非对称加密。