7. HTTP/1.1 有什么优缺点
参考文章:《HTTP/1.0 HTTP/1.1 HTTP/2.0 主要特性对比》
对于 HTTP/1.1
,不仅继承了 HTTP1.0
简单的特点,还克服了诸多 HTTP1.0
性能上的问题。
7.1 HTTP/1.1 优点
- 增加持久性连接
也就是多个请求和响应可以利用同一个 TCP 连接,而不是每一次请求响应都要新建一个TCP连接,减少了建立和关闭连接的消耗和延迟。
Connection: keep-alive
- 增加管道机制
增加了管道机制,请求可以同时发出,但是响应必须按照请求发出的顺序依次返回,性能在一定程度上得到了改善。
- 分块传输
在 HTTP/1.1 版本中,可以不必等待数据完全处理完毕再返回,服务器产生部分数据,那么就发送部分数据,很明此种方式更加优秀一些,可以节省很多等待时间。
- 增加
host
字段
使得一个服务器能够用来创建多个 Web 站点。
- 错误提示
HTTP/1.1 引入了一个 Warning
头域,增加对错误或警告信息的描述,此外,在 HTTP/1.1 中新增了24个状态响应码(100,101,203,205,206,301,305… )。
- 带宽优化
HTTP/1.1 中在请求消息中引入了 range
头域,它允许只请求资源的某个部分。
在响应消息中 Content-Range
头域声明了返回的这部分对象的偏移值和长度。如果服务器相应地返回了对象所请求范围的内容,则响应码为 206(Partial Content)
,它可以防止 Cache
将响应误以为是完整的一个对象,HTTP/1.1 加入了一个新的状态码 100(Continue)
。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码 401(Unauthorized
);如果服务器接收此请求就回送响应码 100
,客户端就可以继续发送带实体的完整请求了。
注意,HTTP/1.0 的客户端不支持 100 响应码。但可以让客户端在请求消息中加入 Expect
头域,并将它的值设置为 100-continue
。
7.2 HTTP/1.1 缺点
- 队头阻塞
此版本的网络延迟问题主要由于队头堵塞导致,虽然通过持久性连接得到改善,但是每一个请求的响应依然需要按照顺序排队,如果前面的响应处理较为耗费时间,那么同样非常耗费性能。
- 技术不成熟
还有此版本虽然引进了管道机制,但是当前存在诸多问题,且默认处于关闭状态。
- 浪费资源
http/1.1 请求会携带大量冗余的头信息,浪费了很多宽带资源。
8. 相比 HTTP/1.1,HTTP/2.0 有哪些新特性
参考文章:《HTTP1.0 HTTP/1.1 HTTP2.0 主要特性对比》
- 二进制分帧
在应用层(HTTP/2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层,从而突破 HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。
可见,虽然 HTTP/2.0 的协议和 HTTP1.x 协议之间的规范完全不同了,但是实际上 HTTP/2.0并 没有改变 HTTP1.x 的语义。
简单来说,HTTP/2.0 只是把原来 HTTP1.x 的 header
和 body
部分用 frame
重新封装了一层而已。
- 多路复用(连接共享)
允许同时通过单一的 HTTP/2 连接发起多重的请求-响应消息,这个强大的功能则是基于“二进制分帧”的特性。
从图中可见,所有的 HTTP/2.0 通信都在一个 TCP 连接上完成,这个连接可以承载任意数量的双向数据流。
每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id
)重新组装。
- 首部压缩
HTTP1.1 不支持 header
数据的压缩,HTTP/2.0 使用 HPACK
算法对 header
的数据进行压缩,这样数据体积小了,在网络上传输就会更快。高效的压缩算法可以很大的压缩 header
,减少发送包的数量从而降低延迟。
- 服务器推送
在 HTTP/2 中,服务器可以对客户端的一个请求发送多个响应,即服务器可以额外的向客户端推送资源,而无需客户端明确的请求。
9. 请简述 HTTPS 工作原理
9.1 HTTPS 简介
参考文章:《深入浅出讲解HTTPS工作原理》
HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。
通常,HTTP 直接和 TCP 通信。当使用 SSL 时,则演变成先和 SSL 通信,再由 SSL 和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP。
在采用 SSL 后,HTTP 就拥有了 HTTPS 的加密、证书和完整性保护这些功能。也就是说HTTP 加上加密处理和认证以及完整性保护后即是 HTTPS。
HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
9.2 HTTPS 工作原理
HTTPS 其实是有两部分组成:HTTP + SSL / TLS,也就是在 HTTP 上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过 TLS 进行加密,所以传输的数据都是加密后的数据。
- 客户端发起HTTPS请求
浏览器里面输入一个HTTPS网址,然后连接到服务端的443端口上。注意这个过程中客户端会发送一个密文族给服务端,密文族是浏览器所支持的加密算法的清单。
- 服务端配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。
这套证书其实就是一对公钥和私钥,可以这么理解,公钥就是一把锁头,私钥就是这把锁的钥匙,锁头可以给别人对某个东西进行加锁,但是加锁完毕之后,只有持有这把锁的钥匙才可以解锁看到加锁的内容。
- 传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构、过期时间等等。
- 客户端解析证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,如颁发机构、过期时间等等,如果发现异常则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密。
注意一下上面提到的"发现异常"。证书中会包含数字签名,该数字签名是加密过的,是用颁发机构的私钥对本证书的公钥、名称及其他信息做hash散列加密而生成的。客户端浏览器会首先找到该证书的根证书颁发机构,如果有,则用该根证书的公钥解密服务器下发的证书,如果不能正常解密,则就是"发现异常",说明该证书是伪造的。
- 传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,然后客户端和服务端的通信就可以通过这个随机值来进行加密和解密了。
- 服务端解密信息
服务端用私钥解密后,得到了客户端传过来的随机值,至此一个非对称加密的过程结束,看到TLS利用非对称加密实现了身份认证和密钥协商。然后把内容通过该值进行对称加密。
- 传输加密后的信息
这部分是服务端用随机值加密后的信息,可以在客户端被还原。
- 客户端解密信息
客户端用之前生成的随机值解密服务端传送过来的信息,于是获取了解密后的内容,至此一个对称加密的过程结束,看到对称加密是用于对服务器待传送给客户端的数据进行加密用的。整个过程即使第三方监听了数据,也束手无策。
10. HTTP 和 HTTPS 的共同点和区别
- https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。
- http 是超文本传输协议,信息是明文传输, https 则是具有安全性的ssl加密传输协议。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http 的连接很简单,是无状态的; HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
11. 什么是跨域,如何解决跨域
参考文章:《前端常见跨域解决方案(全)》
11.1 什么是跨域
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
- 什么是同源策略?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到 XSS 、 CSFR 等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
- 同源策略限制了以下行为:
Cookie
、LocalStorage
和IndexDB
无法读取DOM
和JS
对象无法获取Ajax
请求发送不出去
- 常见跨域场景:
所谓的同源是指:域名、协议、端口均为相同。
http://www.a.cn/index.html
调用http://www.a.cn/server.php
非跨域。http://www.a.cn/index.html
调用http://www.b.cn/server.php
跨域,主域不同。http://abc.a.cn/index.html
调用http://def.b.cn/server.php
跨域,子域名不同。http://www.a.cn:8080/index.html
调用http://www.a.cn/server.php
跨域,端口不同。https://www.a.cn/index.html
调用http://www.a.cn/server.php
跨域,协议不同。localhost
调用127.0.0.1
跨域。
11.2 解决跨域
jsonp
跨域document.domain
+iframe
跨域window.name
+iframe
跨域location.hash
+iframe
跨域postMessage
跨域- 跨域资源共享
CORS
withCredentials
属性WebSocket
协议跨域node
代理跨域nginx
代理跨域
具体每一种解决方法,可以参考:《前端常见跨域解决方案(全)》
12. HTTP 中与缓存相关的头部有哪些,它们有什么区别
头部 | 优势和特点 | 劣势和问题 |
Expires |
1、HTTP 1.0 产物,可以在HTTP 1.0 和1.1 中使用,简单易用。2、以时刻标识失效时间。 |
1、时间是由服务器发送的(UTC ),如果服务器时间和客户端时间存在不一致,可能会出现问题。2、存在版本问题,到期之前的修改客户端是不可知的。 |
Cache-Control |
1、HTTP 1.1 产物,以时间间隔标识失效时间,解决了Expires 服务器和客户端相对时间的问题。2、比Expires 多了很多选项设置。 |
1、HTTP 1.1 才有的内容,不适用于HTTP 1.0 。2、存在版本问题,到期之前的修改客户端是不可知的。 |
Last-Modified |
1、不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。 | 1、只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。2、以时刻作为标识,无法识别一秒内进行多次修改的情况。3、某些服务器不能精确的得到文件的最后修改时间。 |
ETag |
1、可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。2、不存在版本问题,每次请求都回去服务器进行校验。 | 1、计算ETag 值需要性能损耗。2、分布式服务器存储的情况下,计算ETag 的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时发现ETag 不匹配的情况。 |
13. 分别介绍强缓存和协商缓存
浏览器缓存主要分为强缓存(也称本地缓存)和协商缓存(也称弱缓存)。
13.1 强缓存
强缓存是利用 http
头中的 Expires
和 Cache-Control
两个字段来控制的,用来表示资源的缓存时间。
强缓存中,普通刷新会忽略它,但不会清除它,需要强制刷新。浏览器强制刷新,请求会带上 Cache-Control:no-cache
和 Pragma:no-cache
。
通常,强缓存不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码。分为 from disk cache
和 from memory cache
。
from disk cache
:一般非脚本会存在内存当中,如css,html等from memory cache
:资源在内存当中,一般脚本、字体、图片会存在内存当
有缓存命中和缓存未命中状态:
13.2 协商缓存
协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问。
普通刷新会启用弱缓存,忽略强缓存。只有在地址栏或收藏夹输入网址、通过链接引用资源等情况下,浏览器才会启用强缓存,这也是为什么有时候我们更新一张图片、一个js文件,页面内容依然是旧的,但是直接浏览器访问那个图片或文件,看到的内容却是新的。
这个主要涉及到两组 header
字段: Etag
和 If-None-Match
、 Last-Modified
和 If-Modified-Since
。
向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存。
有缓存命中和缓存未命中状态:
13.3 流程
浏览器第一次发起请求,本地有缓存情况: 在浏览器第一次发起请求时,本地无缓存,向web服务器发送请求,服务器起端响应请求,浏览器端缓存。过程如下:
在第一次请求时,服务器会将页面最后修改时间通过 Last-Modified
标识由服务器发送给客户端,客户端记录修改时间;服务器还会生成一个Etag,并发送给客户端。
浏览器后续再次进行请求时:
14. 请简单介绍一下 LRU (Least recently used)算法
参考文章:《LRU算法》
14.1 原理
LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。
这里有一张比较卡通的图片:
14.2 实现
最常见的实现是使用一个链表保存缓存数据,详细算法实现如下:
- 新数据插入到链表头部;
- 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
- 当链表满的时候,将链表尾部的数据丢弃。
14.3 分析
- 命中率
当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。
- 复杂度
实现简单。
- 代价
命中时需要遍历链表,找到命中的数据块索引,然后需要将数据移到头部。
结语
本文主要复习了 HTTP/HTTPS 的一些基础知识,还有 HTTP 的其他版本的知识,对于面试也好,知识沉淀也好,这些也是我们作为开发者必须懂的。
作为一名前端开发者,说实话对 HTTP/HTTPS 了解还是太少,可能和平常工作内容有关。