一、HTTP协议
GET和POST的请求的区别
从缓存的角度,GET 请求会被浏览器主动缓存下来,留下历史记录,而 POST 默认不会。
从编码的角度,GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
从参数的角度,GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输敏感信息。
从TCP的角度,GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应 100(continue), 然后发 body 部分。(火狐浏览器除外,它的 POST 请求只发一个 TCP 包)
从幂等性的角度,GET是幂等的,而POST不是。(幂等表示执行相同的操作,结果也是相同的)
POST和PUT请求的区别
PUT请求是向服务器端发送数据,从而修改数据的内容,但是不会增加数据的种类等
POST请求是向服务器端发送数据,该请求会改变数据的种类等资源,它会创建新的内容。(可以理解为是创建数据)
常见的HTTP请求头和响应头
HTTP Request Header 常见的请求头:
Accept:浏览器能够处理的内容类型, Accept: text/html, Accept: /
Accept-Charset:浏览器能够显示的字符集
Accept-Encoding:浏览器能够处理的压缩编码 gzip, deflate, br
Accept-Language:浏览器当前设置的语言zh-CN,zh;q=0.9
Connection:浏览器与服务器之间连接的类型keep-alive/close
Cookie:当前页面设置的任何Cookie
Host:发出请求的页面所在的域,www.baidu.com
Referer:发出请求的页面的URL
User-Agent:浏览器的用户代理字符串
HTTP Responses Header 常见的响应头:
Date:表示消息发送的时间,时间的描述格式由rfc822定义
Expris:
server:服务器名称
Connection:浏览器与服务器之间连接的类型
Cache-Control:控制HTTP缓存
Content-type:告诉客户端,资源文件的类型以及字符编码Content-Type: text/html;charset=utf-8
Content-Encoding:gzip 告诉客户端,服务端发送的资源是采用gzip编码的
Content-Language
HTTP请求报文的是什么样的?
请求行:请求⽅法字段、URL字段、HTTP协议版本字段。它们⽤空格分隔。例如,GET /index.html HTTP/1.1。
请求头部:请求头部由关键字/值对组成,例如
User-Agent:产⽣请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处⼀个IP地址,即虚拟主机。
空行
请求体:post put等请求携带的数据
HTTP响应报文的是什么样的?
响应hang:由网络协议版本,状态码和状态码的原因短语组成,例如 HTTP/1.1 200 OK
响应头:
空行:
响应体:服务器响应的数据
HTTP协议的优点和缺点
优点:
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
请求-应答,有来有回;
可靠传输,继承TCP/IP的特性;
无状态:HTTP 协议是无状态协议,这里的状态是指通信过程的上下文信息。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能会导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就比较快。
灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
缺点:
无状态:HTTP 是一个无状态的协议,HTTP 服务器不会保存关于客户的任何信息。
明文传输:协议中的报文使用的是文本形式,这就直接暴露给外界,不安全。
队头阻塞问题
当 http 开启长连接时,共用一个 TCP 连接,同一时刻只能处理一个请求,那么当前请求耗时过长的情况下,其它的请求只能处于阻塞状态,也就是著名的队头阻塞问题。
如何解决队头阻塞?
(1)并发连接:对于一个域名允许分配多个长连接,那么相当于增加了任务队列,不至于一个队伍的任务阻塞其它所有任务。
(2)域名分片:将域名分出很多二级域名,它们都指向同样的一台服务器,能够并发的长连接数变多,解决了队头阻塞的问题。
常见的HTTP请求方法
GET: 向服务器获取数据;
POST:是向服务器端发送数据,该请求会改变数据的种类等资源,它会创建新的内容。
PUT:是向服务器端发送数据,从而修改数据的内容,但是不会增加数据的种类等,上传文件,更新数据;
DELETE:删除服务器上的对象;
HEAD:获取报文首部,与GET相比,不返回报文主体部分;
OPTIONS:询问支持的请求方法,用来跨域请求;
CONNECT:要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信;
TRACE: 回显服务器收到的请求,主要⽤于测试或诊断。
对keep-alive的理解
当使用Keep-Alive模式时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接
Keep-Alive的建立过程:
客户端向服务器在发送请求报文同时在首部添加发送Connection字段
服务器收到请求并处理 Connection字段
服务器回送Connection:Keep-Alive字段给客户端
客户端接收到Connection字段
Keep-Alive连接建立成功
URL有哪些组成部分
scheme:// user:passwd@ host:port path ?query #fragment
scheme 表示协议名,比如http, https, file等等。后面必须和://连在一起。
user:passwd@ 表示登录主机时的用户信息,不过很不安全,不推荐使用,也不常用。
host:port表示主机名(域名)和端口。
path表示请求路径,标记资源所在位置。
query表示查询参数,为key=val这种形式,多个键值对之间用&隔开。
fragment表示 URI 所定位的资源内的一个锚点,浏览器可以根据这个锚点跳转到对应的位置。
https://www.baidu.com/s?wd=HTTP&rsv_spt=1 这个 URI 中,https即scheme部分,www.baidu.com为host:port部分,域名部分:端口号(注意,http 和 https 的默认端口分别为80、443),/s为path部分,而wd=HTTP&rsv_spt=1就是query部分。
端口号的作用
一台主机(对应一个IP地址)可以提供很多服务,比如web服务,ftp服务等。如果只有一个IP,就无法区分不同的网络服务,所以采用”IP+端口号”来区分不同的服务。
OPTIONS请求方法及使用场景???
旨在发送一种探测请求,以确定针对某个目标地址的请求必须具有怎么样的约束,然后根据约束发送真正的请求。
比如针对跨域资源的预检,就是采用 HTTP 的 OPTIONS 方法先发送的。用来处理跨域请求。
HTTP 1.0 和 HTTP 1.1 之间有哪些区别
连接方面:http1.0 默认使用非持久连接,而 http1.1 默认使用持久连接。http1.1 通过使用持久连接来使多个 http 请求复用同一个 TCP 连接,以此来避免使用非持久连接时每次需要建立连接的时延。
资源请求方面:在 http1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,http1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content)
缓存方面:在 http1.0 中主要使用 header 里的 If-Modified-Since、Expires 来做为缓存判断的标准,http1.1 则引入了更多的缓存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略。
host: http1.1 中新增了 host 字段,用来指定服务器的域名。http1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。
请求方法:http1.1 相对于 http1.0 还新增了很多请求方法,如 PUT、HEAD、OPTIONS 等
HTTP 1.1 和 HTTP 2.0 的区别
头部压缩:
在 HTTP/1.1 及之前的时代,请求体一般会有响应的压缩编码过程,通过Content-Encoding头部字段来指定,对于头部字段,当请求字段非常复杂的时候,尤其对于 GET 请求,请求报文几乎全是请求头,这个时候还是存在非常大的优化空间的。HTTP/2 针对头部字段,也采用了对应的压缩算法——HPACK,对请求头进行压缩
HPACK算法:首先是在服务器和客户端之间建立哈希表,将用到的字段存放在这张表中,那么在传输的时候对于之前出现过的值,只需要把索引(比如0,1,2,…)传给对方即可;其次是对于整数和字符串进行哈夫曼编码,哈夫曼编码的原理就是先将所有出现的字符建立一张索引表,然后让出现次数多的字符对应的索引尽可能短,传输的时候也是传输这样的索引序列,可以达到非常高的压缩率。
多路复用:
HTTP/2 实现了多路复用,HTTP/2 仍然复用 TCP 连接,但是在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一发送,这样就避免了"队头堵塞"的问题;
何为队头阻塞?
HTTP 队头阻塞的问题,其根本原因在于HTTP 基于请求-响应的模型,在同一个 TCP 长连接中,前面的请求没有得到响应,后面的请求就会被阻塞。
如何解决的?
通信双方都可以给对方发送二进制帧,这种二进制帧的双向传输的序列,也叫做流(Stream)。HTTP/2 用流来在一个 TCP 连接上来进行多个数据帧的通信,这就是多路复用
服务器推送:
HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源(静态资源),这样就可以相对减少一些延迟时间。
HTTP1 HTTP2 HTTP3区别
最大的区别就是多路复用:HTTP1在一个TCP连接中只能发送一个请求和响应,或者是长期建立链接之后也是一个请求和发送结束之后在进行下一个导致阻塞。
但是HTTP2在一个TCP连接中可以发送和响应多个请求,并且是并行的,实现了多路复用。
HTTP2采用的是TCP协议实现的多路复用。 实现原理:HTTP2引入了一个二进制分帧层,客户端和服务端进行传输时,数据会先经过二进制分帧层处理,转化为一个个带有请求ID的帧,这些帧在传输完成后根据ID组合成对应的数据。
HTTP3采用的是UDP协议实现TCL的多路复用,并且加了TLS加密传输,已经在往HTTPS协议发展了。
GET方法URL长度限制的原因
实际上HTTP协议规范并没有对get方法请求的url长度进行限制,这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35),最长不超过2083个字符,这样所有的浏览器和服务器都可能正常工作。
页面有多张图片,HTTP是怎样的加载表现???
HTTP2可以一下请求很多资源,因为HTTP2支持多路复用,同一个TCP链接可以发送多个请求。
HTTP1对于同一域名的TCP允许的最大连接数是6,并且一个TCP链接只能发送一个请求,所以需要发送好多个TCP链接和好多个请求,解决方法,用多域名部署多张图片。
HTTP2的头部压缩算法是怎样的
HPACK算法:
首先是在服务器和客户端之间建立哈希表,将用到的字段存放在这张表中,那么在传输的时候对于之前出现过的值,只需要把索引(比如0,1,2,…)传给对方即可;
其次是对于整数和字符串进行哈夫曼编码,哈夫曼编码的原理就是先将所有出现的字符建立一张索引表,然后让出现次数多的字符对应的索引尽可能短,传输的时候也是传输这样的索引序列,可以达到非常高的压缩率。
HTTP 如何实现长连接?在什么时候会超时?
通过在头部(请求和响应头)设置 Connection: keep-alive,HTTP1.0协议支持,但是默认关闭,从HTTP1.1协议以后,连接默认都是长连接。
Keep-Alive timeout:
HTTP 一般会有 httpd 守护进程,里面可以设置 keep-alive timeout,当 tcp 链接闲置超过这个时间就会关闭,也可以在 HTTP 的 header 里面设置超时时间
Tcp的Keep-alive:
TCP 的 keep-alive 包含三个参数,支持在系统内核的 net.ipv4 里面设置:当 TCP 链接之后,闲置了 tcp_keepalive_time,则会发生侦测包,如果没有收到对方的 ACK,那么会每隔 tcp_keepalive_intvl 再发一次,直到发送了 tcp_keepalive_probes次,仍然没有收到对方的ack包,就会丢弃该链接。
tcp_keepalive_intvl = 15
tcp_keepalive_probes = 5
tcp_keepalive_time = 1800
实际上 HTTP 没有长短链接,只有 TCP 有,TCP 长连接可以复用一个 TCP 链接来发起多次 HTTP 请求,这样可以减少资源消耗,比如一次请求 HTML,可能还需要请求后续的 JS/CSS/图片等
http缓存的作用?
节省资源,节省流量,节省时间,也就是所谓的优化。
时间:
通常情况下通过网络获取内容速度慢成本高,有些响应需要在客户端和服务器之间进行多次往返通信,这就拖延了浏览器可以使用和处理内容的时间,同时也增加了访问者的数据成本。
资源:
通过缓存,使用资源副本,大大减少获取资源时间,
流量:
能够减少网络带宽消耗、减少延迟与网络阻塞,同时降低服务器压力,提高服务器性能。
HTTP缓存方式
两种缓存方式,根据响应的header内容来决定
强缓存(状态码:200):浏览器不向服务器发送任何请求,直接从本地缓存中读取文件并返回(相关字段:Cache-Control、Expires)
协商缓存(状态码304):浏览器发送请求到服务器,通过服务器来告知缓存是否可用(相关字段:Last-Modified/If-Modified-Since、Etag/If-None-Match)
强缓存
强缓存:使用强缓存策略时,如果缓存资源有效,则直接使用缓存资源,不必再向服务器发起请求。
Expires:服务器通过在响应头中添加 Expires 属性,来指定资源的过期时间。在过期时间以内,该资源可以被缓存使用,不必再向服务器发送请求。这个时间是一个绝对时间,它是服务器的时间,因此可能存在这样的问题,就是客户端的时间和服务器端的时间不一致,或者用户可以对客户端时间进行修改的情况,这样就可能会影响缓存命中的结果。Expires 是 http1.0 中的方式,因为它的一些缺点,在 HTTP 1.1 中提出了一个新的头部属性就是 Cache-Control 属性。
Cache-Control:
*max-age=xxx:缓存的内容将在 xxx 秒后失效,这个选项只在 HTTP1.1 可用,并如果和 Last-Modified 一起使用时,优先级较高。
*no-cache: 在浏览器使用缓存前,会往返对比 ETag,如果 ETag 没变,返回 304,则使用协商缓存。no-cache的目的就是为了防止从缓存中获取过期的资源。
*no-store: 彻底禁用缓存,所有内容都不会被缓存到缓存或临时文件中,每次都会向服务端发起新的请求,拉取最新的资源;
*public: 所有内容都将被缓存(客户端和代理服务器都可缓存)
*private: 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)
协商缓存
它是一种服务端的缓存策略,即通过服务端来判断某件事情是不是可以被缓存。
使用协商缓存策略时,服务端判断客户端的资源,是否和服务端资源一样,如果一致则返回 304 ,反之返回 200 和最新的资源。
在响应头部 Response Headers 中,有两种资源标识:
Last-Modified 资源的最后修改时间,对应请求头为 If-Modified-Since ;
Etag 资源的唯一标识,所谓唯一,可以想象成时人类的指纹,具有唯一性;但 Etag 的本质是一个字符串;对应请求头为 If-None-Match
Last-Modified 和 Etag
当响应头部 Response Headers 同时存在 Last-Modified 和 Etag 的值时,会优先使用 Etag ;
Last-Modified 只能精确到秒级;
如果资源被重复生成,而内容不变,则 Etag 更精确
https://juejin.cn/post/6974529351270268958#heading-18
浏览器缓存的全过程
浏览器第一次加载资源,服务器返回 200,浏览器从服务器下载资源文件,并缓存资源文件与 response header,以供下次加载时对比使用;
下一次加载资源时,由于强制缓存优先级较高,先比较当前时间与上一次返回 200 时的时间差,如果没有超过 cache-control 设置的 max-age,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用 expires 头判断是否过期;
如果资源已过期,则表明强制缓存没有被命中,则开始协商缓存,向服务器发送带有 If-None-Match(Etag) 和 If-Modified-Since (last-Modifined)的请求;
服务器收到请求后,优先根据 Etag 的值判断被请求的文件有没有做修改,Etag 值一致则没有修改,命中协商缓存,返回 304;如果不一致则有改动,直接返回新的资源文件带上新的 Etag 值并返回 200;
如果服务器收到的请求没有 Etag 值,则将 If-Modified-Since 和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified 和文件并返回 200;
为什么需要浏览器缓存?
如果没有缓存的话,每一次网络请求都要加载大量的图片和资源,这会使页面的加载变慢许多。那缓存的目的其实就是为了尽量减少网络请求的体积和数量,让页面加载的更快。
使用浏览器缓存,有以下优点:
减少了服务器的负担,提高了网站的性能
加快了客户端网页的加载速度
减少了多余网络数据传输
哪些资源可以被缓存?——静态资源(js、css、img)
网站的 html 是不能被缓存的。因为网站在使用过程中 html 随时有可能被更新,随时有可能被替换模板。
网页的业务数据也是不能被缓存的。比如留言板和评论区,用户随时都可以在底下评论,那数据库的内容就会被频繁被更新
点击刷新按钮或者按 F5、按 Ctrl+F5 (强制刷新)、地址栏回车有什么区别?
点击刷新按钮或者按 F5:强制缓存失效,协商缓存有效
浏览器直接对本地的缓存文件过期,但是会带上If-Modifed-Since,If-None-Match,这就意味着服务器会对文件检查新鲜度,返回结果可能是 304,也有可能是 200
用户按 Ctrl+F5(强制刷新):强制缓存失效,协商缓存失效
浏览器不仅会对本地文件过期,而且不会带上 If-Modifed-Since,If-None-Match,相当于之前从来没有请求过,返回结果是 200
地址栏回车:强制缓存有效,协商缓存有效
浏览器发起请求,按照正常流程,本地检查是否过期,然后服务器检查新鲜度,最后返回内容。
说一下一次完整的HTTP请求过程包括哪些内容?
1、TCP建立连接
HTTP协议是基于TCP协议来实现的,因此首先就是要通过TCP三次握手与服务器端建立连接,一般HTTP默认的端口号为80;
2、浏览器发送请求命令
在与服务器建立连接后,Web浏览器会想服务器发送请求命令
3、浏览器发送请求头消息
在浏览器发送请求命令后,还会发送一些其它信息,最后以一行空白内容告知服务器已经完成头信息的发送;
4、服务器应答
在收到浏览器发送的请求后,服务器会对其进行回应,应答的第一部分是协议的版本号和应答状态码;
5、服务器回应头信息
与浏览器端同理,服务器端也会将自身的信息发送一份至浏览器
6、服务器发送数据
在完成所有应答后,会以Content-Type应答头信息所描述的格式发送用户所需求的数据信息
7、断开TCP连接
在完成此次数据通信后,服务器会通过TCP四次挥手主动断开连接。但若此次连接为长连接,那么浏览器或服务器的头信息会加入keep-alive的信息,会保持此连接状态,在有其它数据发送时,可以节省建立连接的时间;
当在浏览器中输入 Google.com 并且按下回车之后发生了什么?
根据域名,进行DNS域名解析;
拿到解析的IP地址,建立TCP连接;
向IP地址,发送HTTP请求; 浏览器发送HTTP请求报文
服务器处理请求;
返回响应结果; 服务器返回HTTP响应报文
关闭TCP连接;
浏览器解析HTML;
浏览器布局渲染;
二、HTTPS协议
什么是HTTPS协议?
超文本传输安全协议(Hypertext Transfer Protocol Secure,简称:HTTPS)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,利用SSL/TLS来加密数据包。HTTPS的主要目的是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
放在HTTP和TCP之间,通过HTTP传输,数据包用SSL/TLS进行加密,HTTP 与 TCP 通信的时候,必须先进过一个安全层,对数据包进行加密,然后将加密后的数据包传送给 TCP,相应的 TCP 必须将数据包解密,才能传给上面的 HTTP。
HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具有身份验证、信息加密和完整性校验的功能,可以避免此类问题发生。
TLS/SSL的工作原理
(1)散列函数hash
(2)对称加密
(3)非对称加密
包括三个
非对称加密:实现身份验证和密钥协商。我们又两个秘钥,公钥和私钥,公钥是公开的,私钥的私密的。公钥发布的内容只能由对应的私钥来解密,私钥发送的内容也只能由对应的公钥来解密。一台服务器向多个客户端发送同一个公钥,与不同的客户端建立联系,当某一个客户端想要访问该服务器的数据的时候,就会向该服务器发送一个公钥,该服务器用自己的私钥进行解密。
对称加密:利用协商的秘钥对数据进行加密。客户端和服务端使用同一个私钥。
函数散列hash值:验证数据包的完整性。
为什么需要对称加密和非对称加密?如何确保对称加密的秘钥进行安全传输呢,这时候就需要非对称加密。但是非对称加密非常慢,这时候就需要对称加密了。
数字证书是什么?
定义:为了防止中间人攻击,对客户端和服务端产生假的秘钥,采用数字证书。
原理:首先使用一种hash算法对公钥和其他信息加密形成信息摘要,然后这个信息摘要通过数字证书的认证中心的私钥进行加密形成签名,最后将原始信息和签名组合形成数字证书。当接收方收到该数字证书的时候根据原始信息使用相同的hash算法生成摘要,然后用数字证书的公钥进行解密得到摘要,看一下生成的摘要和解密的摘要是不是一个,依次来验证数据有没有被更改,还能验证数据的完整性。
HTTPS通信(握手)过程
说法1:
浏览器传输一个 client_random 和加密方法列表;
服务器收到后,传给浏览器一个 server_random、加密方法列表和数字证书(包含了公钥);
然后浏览器对数字证书进行合法验证,如果验证通过,则生成一个 pre_random,然后用公钥加密传给服务器;
服务器用 client_random、server_random 和 pre_random ,使用公钥加密生成 secret,然后之后的传输使用这个 secret 作为秘钥来进行数据的加解密。
说法2:
客户端通过URL发起HTTPS请求,要求服务器建立SSL链接,客户端发送一个随机值,需要的协议和加密方式
服务端收到客户端的随机值,自己也产生一个随机值,并根据客户端需求的协议和加密方式来使用对应的方式,发送自己的证书(如果需要验证客户端证书需要说明)
客户端收到服务端的证书并验证是否有效,验证通过会再生成一个随机值,通过服务端证书的公钥去加密这个随机值并发送给服务端,如果服务端需要验证客户端证书的话会附带证书
服务端收到加密过的随机值并使用私钥解密获得第三个随机值,这时候两端都拥有了三个随机值,可以通过这三个随机值按照之前约定的加密方式生成密钥,接下来的通信就可以通过该密钥来加密解密
HTTPS是如何保证安全的?
结合两种加密⽅式,将对称加密的密钥使⽤⾮对称加密的公钥进⾏加密,然后发送出去,接收⽅使⽤私钥进⾏解密得到对称加密的密钥,然后双⽅可以使⽤对称加密来进⾏沟通。
什么是中间人攻击?
此时⼜带来⼀个问题,MITM中间人攻击:攻击者相当于一个介入通信的传话员,攻击者知道通信双方的所有通信内容且可以任意增加、删除、修改双方的通信内容,而双方对此并不知情。
如果此时在客户端和服务器之间存在⼀个中间⼈,这个中间⼈只需要把原本双⽅通信互发的公钥,换成⾃⼰的公钥,这样中间⼈就可以轻松解密通信双⽅所发送的所有数据。
所以这个时候需要⼀个安全的第三⽅颁发证书CA,证明身份的身份,防⽌被中间⼈攻击。 证书中包括:签发者、证书⽤途、使⽤者公钥、使⽤者私钥、使⽤者的HASH算法、证书到期时间等。
但是问题来了,如果中间⼈篡改了证书,那么身份证明是不是就⽆效了?这个证明就⽩买了,这个时候需要⼀个新的技术,数字签名。
数字签名就是⽤CA⾃带的HASH算法对证书的内容进⾏HASH得到⼀个摘要,再⽤CA的私钥加密,最终组成数字签名。当别⼈把他的证书发过来的时候,我再⽤同样的Hash算法,再次⽣成消息摘要,然后⽤CA的公钥对数字签名解密,得到CA创建的消息摘要,两者⼀⽐,就知道中间有没有被⼈篡改了。这个时候就能最⼤程度保证通信的安全了。
http/https区别
超文本传输安全协议(Hypertext Transfer Protocol Secure,简称:HTTPS)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,利用SSL/TLS来加密数据包。
HTTPS 是在 HTTP 和 TCP 之间建立了一个安全层,HTTP 与 TCP 通信的时候,必须先进过一个安全层,对数据包进行加密,然后将加密后的数据包传送给 TCP,相应的 TCP 必须将数据包解密,才能传给上面的 HTTP。
其实HTTPS就是从HTTP加上加密处理(一般是SSL安全通信线路)+认证+完整性保护;
HTTPS能够进行信息加密、完整性校验和身份验证,很大程度上避免了HTTP协议容易发生信息窃听、信息篡改、信息劫持的风险。
区别:
HTTPS需要使用SSL证书;HTTP不用
端口不一样,http是80,https443
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
HTTPS基于传输层;HTTP基于应用层;
http和https使用的是完全不同的连接方式(http的连接很简单,是无状态的;HTTPS 协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。)
三、HTTP状态码
状态码
- 1xx 表示目前是协议处理的中间状态,还需要后续操作
- 2XX (Success 成功状态码)
(1)200 OK
(2)204 No Content 表示请求成功,但响应报文不含实体的主体部分
(3)206 Partial Content 进行范围请求,表示部分内容,它的使用场景为 HTTP 分块下载和断点续传,当然也会带上相应的响应头字段Content-Range - 3XX (Redirection 重定向状态码)
(1)301 Moved Permanently 永久性重定向,表示资源已被分配了新的 URL
(2)302 Found 临时性重定向,表示资源临时被分配了新的 URL
(3)303 See Other 表示资源存在着另一个 URL,应使用 GET 方法获取资源
(4)304 Not Modified 表示服务器允许访问资源,但因发生请求未满足条件的情况,协商缓存命中的情况
(5)307 Temporary Redirect 临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求; - 4XX (Client Error 客户端错误状态码)
(1)400 Bad Request 请求报文存在语法错误
(2)401 Unauthorized 表示发送的请求需要有通过 HTTP 认证的认证信息
(3)403 Forbidden 服务器禁止访问
(4)404 Not Found 表示没在服务器上找到相应的资源
(5)405 Method Not Allowed 请求方法不被服务器端允许 - 5XX (Server Error 服务器错误状态码)
(1)500 Internal Server Error 表示服务器端在执行请求时发生了错误
(2)501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
(3)502 Bad Gateway 服务器自身是正常的,但访问的时候出错了
(4)503 Service Unavailable 表明服务器暂时处于超负载或正在停机维护,无法处理请求 - 同样是重定向,307,303,302的区别?
302是http1.0的协议状态码,在http1.1版本的时候为了细化302状态码⼜出来了两个303和307。 303明确表示客户端应当采⽤get⽅法获取资源,他会把POST请求变为GET请求进⾏重定向。 307会遵照浏览器标准,不会从post变为get。
HTTP状态码304是多好还是少好
服务器为了提高网站访问速度,对之前访问的部分页面指定缓存机制,当客户端在此对这些页面进行请求,服务器会根据缓存内容判断页面与之前是否相同,若相同便直接返回304,此时客户端调用缓存内容,不必进行二次下载。
状态码304不应该认为是一种错误,而是对客户端有缓存情况下服务端的一种响应。
产生较多304状态码的原因:
页面更新周期长或不更新
纯静态页面或强制生成静态html
304状态码出现过多会造成以下问题:
网站快照停止;
收录减少;
权重下降
四、DNS协议介绍
DNS 协议是什么
DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)
DNS同时使用TCP和UDP协议?
(1)在区域传输的时候使用TCP协议
辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。而且 TCP 是一种可靠连接,保证了数据的准确性。
(2)在域名解析的时候使用UDP协议
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
在浏览器向本机的DNS服务器发送请求的时候不需要提前握手,采用UDP协议;当DNS服务器向上级域名服务器发送请求的时候,因为需要保证传输的安全,所以需要先握手,采用TCP协议。
DNS完整的查询过程
- 当用户输入域名时,首先检查浏览器的DNS缓存,如果查找到直接返回
2)若没命中,则检查操作系统缓存(如Windows的hosts)如果查找到,就直接将查找结果返回
3)若无命中,则请求本地域名服务器解析(LDNS)。注意:主机和本地域名服务器之间的查询是递归查询;
4)若LDNS没有命中,本地域名服务器就像根域名服务器发起请求,根域名服务器返回给LDNS一个 顶级域名服务器地址。
5) 此时LDNS再向 gTLD( 通用顶级域)发送请求, 获取权限域名服务器的地址。
6)本地域名服务器根据权限域名服务器的地址发起请求,最终得到该域名对应的IP地址。(查找并返回这个域名对应的Name Server的地址,Name Server根据映射关系表找到目标ip,返回给LDNS)
7)本地域名服务器将得到的 IP 地址返回给操作系统,同时自己将 IP 地址缓存起来
8)操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来
9)至此,浏览器就得到了域名对应的 IP 地址,并将 IP 地址缓存起来
迭代查询与递归查询
递归查询指的是查询请求发出后,域名服务器代为向下一级域名服务器发出请求,最后向用户返回查询的最终结果。使用递归 查询,用户只需要发出一次查询请求。
迭代查询指的是查询请求后,域名服务器返回单次查询的结果。下一级的查询由用户自己请求。使用迭代查询,用户需要发出 多次的查询请求。
一般我们向本地 DNS 服务器发送请求的方式就是递归查询,而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程。
五、网络模型
OSI七层模型
(1)应用层:为应用程序提供服务。应用层的网络协议:
FTP:文本传输协议
SMTP:简单邮件传输协议
TELNET:Internet远程登录服务的标准协议和主要方式
HTTP:超文本传输协议
TFTP:简单文件传输协议
DNS:域名系统
SNMP:简单网络管理协议
NFS:网络文件系统
(2)表示层:数据格式转化,数据加密。
(3)会话层:建立或解除与别的节点的联系。
(4)传输层:提供端对端的接口,TCP/UDP,而传输层则规定了数据包的传输方式。
(5)网络层:IP选址与路由选择,IP/ICMP/IGMP,网络层规定了数据包的传输路线。
(6)数据链路层:提供介质访问和链路管理,数据链路层也就是传输路线。
(7)物理层:以二进制数据格式在物理介质上传输数据。
TCP/IP四层协议
第一层:应用层,主要有负责web浏览器的HTTP协议, 文件传输的FTP协议,负责电子邮件的SMTP协议,负责域名系统的DNS等。
第二层:传输层,主要是有可靠传输的TCP协议,特别高效的UDP协议。主要负责传输应用层的数据包。
第三层:网络层,主要是IP协议。主要负责寻址(找到目标设备的位置)
第四层:数据链路层,主要是负责转换数字信号和物理二进制信号。
http和tcp区别
TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开
六、TCP与UDP
TCP 和 UDP的概念及特点
TCP的全称是传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
可以进行丢包时的重发;
可以对次序乱掉的分包进行顺序控制;
作为一种面向有连接的协议,只有在确认通信对端的存在的时候才会发送数据;
可以控制流量的浪费;
UDP的全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点。无法使用流量控制避免网络拥堵的情况,传输途中即使出现丢包也不负责重发,当出现包的到达顺序乱掉的时候也没有纠正的功能。
TCP和UDP的区别
UDP TCP
是否连接:
无连接 面向连接
是否可靠:
不可靠传输,不使用流量控制和拥塞控制
可靠传输(数据顺序和正确性),使用流量控制和拥塞控制
连接对象个数:
支持一对一,一对多,多对一和多对多交互通信
只能是一对一通信
传输方式:
面向报文 面向字节流
首部开销:
首部开销小,仅8字节
首部最小20字节,最大60字节
使用场景:
适用于实时应用,例如视频会议、直播
适用于要求可靠传输的应用,例如文件传输
1、有无连接,TCP有链接先建立客户端和服务器端的握手,然而UDP不会先握手,只是在报文前边加一个UDP就传输给IP层
2、传输,UPD传输的是报文,就是发送整个报文,带边界的那种;TCP传输的是数据流,不区分报文边界。
3、安全性。UPD因为没有提前握手所以不安全,TCP提前握手了,所以更安全。
4、UPD可以一对多,多对多,因为没有提前的握手,不需要建立一对一的传输;然而TCP实现的是一对一的传输。
5、应用场景:UPD应用于实时的视频会议,qq聊天等,有实时传输需求的场景;TCP应用于对安全传输要求高,但是不要求效率的场景,比如文件的传输,邮件的传送和用户的登录场景。
TCP和UDP的使用场景
TCP应用场景: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。
UDP应用场景: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)
UDP协议为什么不可靠?
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
不保证消息交付:不确认,不重传,无超时
不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
不跟踪连接状态:不必建立连接或重启状态机
不进行拥塞控制:不内置客户端或网络反馈机制
TCP的三次握手和四次挥手
SYN:标识位,表示建立链接
ACK:标识位,表示响应
FIN:标识位,表示关闭链接
seq:顺序号码(TCP连接中传送的字节流中的每个字节都按顺序编号)
ack:确认号码,是期望收到对方下一个报文的第一个数据字节的序号
(1)三次握手
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
三次握手主要流程:
一开始双方处于close状态,然后服务器开始监听某个端口进入listen状态;
第一次握手:
然后客户端主动发起连接,发送一个SYN报文,然后自己变为SYN-SENT,(首部的同步位SYN=1,初始序号seq=x,SYN=1的报文不能携带数据,但要消耗一个序号)
第二次握手:
服务端收到连接请求报文段后,如果同意连接,则会发送一个应答(ACK + SYN),该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态 (在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y)
第三次握手:
当客户端收到连接同意的应答后,还要向服务端发送一个确认报文(ACK)。客户端发完这个报文段后便进入ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1)
为什么不是两次?
无法确认客户端的接受能力
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。但是此时客户端已经关闭连接了,忽略了服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,所以带来了链接资源的浪费。
hello,你能听到吗?
我能听到呀
hello,你能听到吗?
我能听到啊
三次握手可以携带数据吗?
第三次握手的时候,可以携带。前两次握手不能携带数据。
如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。
第三次握手的时候,客户端已经处于ESTABLISHED状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。
(2)四次挥手
第一次挥手:
若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求,此时客户端处于 FIN_WAIT1 状态。(发出连接释放报文段(FIN=1,序号seq=u)停止再发送数据,主动关闭TCP连接)
第二次挥手:
B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,表示 A 到 B 的连接已经释放,不接收 A 发的数据了。但是因为 TCP 连接时双向的,所以 B 仍旧可以发送数据给 A。(服务端发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
第三次挥手:
B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。(服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1)服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。)
第四次挥手:
A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态。
(发出确认报文段(ACK=1,seq=u+1,ack=w+1)客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。)
为什么 A 要进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态?
为了保证 B 能收到 A 的确认应答。若 A 发完确认应答后直接进入 CLOSED 状态,如果确认应答因为网络问题一直没有到达,那么会造成 B 不能正常关闭。
1个 MSL 保证四次挥手中主动关闭方最后的 ACK 报文能最终到达对端
1个 MSL 保证对端没有收到 ACK 那么进行重传的 FIN 报文能够到达
为什么建立连接是三次握手,关闭连接是四次挥手
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
为什么是四次挥手不是三次?
等于说服务端将ACK和FIN的发送合并为一次挥手,这个时候长时间的延迟可能会导致客户端误以为FIN没有到达客户端,从而让客户端不断的重发FIN。
问:在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?
在 HTTP 中响应体的 Connection 字段指定为 keep-alive
TCP的重传机制
由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间,二是基于确认信息。
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
TCP的拥塞控制机制(算法没写)
上一节所说的流量控制发生在发送端跟接收端之间,并没有考虑到整个网络环境的影响,如果说当前网络特别差,特别容易丢包,那么发送端就应该注意一些了。而这,也正是拥塞控制需要处理的问题。
对于拥塞控制来说,TCP 每条连接都需要维护两个核心状态:
拥塞窗口(Congestion Window,cwnd)
慢启动阈值(Slow Start Threshold,ssthresh)
拥塞窗口(Congestion Window,cwnd)是指目前自己还能传输的数据量大小。那么之前介绍了接收窗口的概念,两者有什么区别呢?
接收窗口(rwnd)是接收端给的限制
拥塞窗口(cwnd)是发送端的限制
限制谁呢?
限制的是发送窗口的大小。
有了这两个窗口,如何来计算发送窗口?
发送窗口大小 = min(rwnd, cwnd)
取两者的较小值。而拥塞控制,就是来控制cwnd的变化。
TCP的流量控制机制(滑动窗口)
对于发送端和接收端而言,TCP 需要把发送的数据放到发送缓存区, 将接收的数据放到接收缓存区。https://juejin.cn/post/6844904070889603085#heading-42
**而流量控制索要做的事情,就是在通过接收缓存区的大小,控制发送端的发送。**如果对方的接收缓存区满了,就不能再继续发送了。
首先双方三次握手,初始化各自的窗口大小,均为 200 个字节。
假如当前发送端给接收端发送 100 个字节,那么此时对于发送端而言,SND.NXT 当然要右移 100 个字节,也就是说当前的可用窗口减少了 100 个字节,这很好理解。
现在这 100 个到达了接收端,被放到接收端的缓冲队列中。不过此时由于大量负载的原因,接收端处理不了这么多字节,只能处理 40 个字节,剩下的 60 个字节被留在了缓冲队列中。
注意了,此时接收端的情况是处理能力不够用啦,你发送端给我少发点,所以此时接收端的接收窗口应该缩小,具体来说,缩小 60 个字节,由 200 个字节变成了 140 字节,因为缓冲队列还有 60 个字节没被应用拿走。
因此,接收端会在 ACK 的报文首部带上缩小后的滑动窗口 140 字节,发送端对应地调整发送窗口的大小为 140 个字节。
此时对于发送端而言,已经发送且确认的部分增加 40 字节,也就是 SND.UNA 右移 40 个字节,同时发送窗口缩小为 140 个字节。
TCP的可靠传输机制 没写
TCP粘包以及解决方案以及UDP为什么不会粘包
TCP传输采用的是延迟传输算法,即先把数据包缓存起来,如果一个很短的时间内有多个数据包传输,那么就会被打包成一个包进行传输,如果传输的是文本,那不会发生粘包,如果发送的是纤消息或者是不同功能的数据包,就会发生粘包问题。
比如send发送一个数据包,里边有data1 data2,那么接收方会有这几种情况
1、先收到data1,在收到data2
2、先收到data1的一部分,在收到data1的剩余部分和data2
3、先收到data1和data2的一部分,在收到data2的剩余部分
4、同时收到data1和data2
解决方法:
1、send完一个数据包之后隔一段时间在send
2、采用封包/拆包的方式,在send一个数据包之前把data1 data2等的前后加上特征数据,当接收方收到数据包之后利用特征数据进行拆包。
UDP为什么不会粘包
因为TCP传输的是数据流,UDP传输的是消息,一条消息就是一个UDP,并且UDP有消息头,包含消息源和端口号,所以不会造成粘包。即使是发送方发送的数据接收方没有完全收到,也不会进行第二次send,不管怎样都是一次结束的。
七、WebSocket
对 WebSocket 的理解
WebSocket是HTML5提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。它基于TCP传输协议,并复用HTTP的握手通道。浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
原理:
客户端向 WebSocket 服务器通知(notify)一个带有所有接收者ID(recipients IDs)的事件(event),服务器接收后立即通知所有活跃的(active)客户端,只有ID在接收者ID序列中的客户端才会处理这个事件。
// 在index.html中直接写WebSocket,设置服务端的端口号为 9999
let ws = new WebSocket('ws://localhost:9999');
// 在客户端与服务端建立连接后触发
ws.onopen = function() {
console.log("Connection open.");
ws.send('hello');
};
// 在服务端给客户端发来消息的时候触发
ws.onmessage = function(res) {
console.log(res); // 打印的是MessageEvent对象
console.log(res.data); // 打印的是收到的消息
};
// 在客户端与服务端建立关闭后触发
ws.onclose = function(evt) {
console.log("Connection closed.");
};
特点:
支持双向通信,实时性更强
可以发送文本,也可以发送二进制数据‘’
建立在TCP协议之上,服务端的实现比较容易
数据格式比较轻量,性能开销小,通信高效
没有同源限制,客户端可以与任意服务器通信
协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器
websokect与AJAX的区别
生命周期不同:
websocket 是长连接,会话一直保持
ajax 发送接收之后就会断开
适用范围:
websocket 用于前后端实时交互数据
ajax 非实时
发起人:
AJAX 客户端发起
WebSocket 服务器端和客户端相互推送