文章目录
- 1、握手一些概念
- 2、三次握手过程理解(2+4+2)
- 3、TCP四次挥手(2+3+4+2)
- 4、TCP和UDP区别
- 5、如何实现UDP可靠传输
- 6、TCP拥塞控制、流量控制
- 5、TCP 滑动窗口和流量控制
- 6、CDN
- 7、dns解析方式:递归 迭代
- 8、HTTP常用的状态码
- 9、TCP\IP协议族各层有什么作用
- 10、HTTP1.0 HTTP 1.1 HTTP 2.0主要区别
- 队头阻塞
- 11、http的常用方法
- 12、http持久连接
- 13、http报文首部
- Content-Type
- 14、前端缓存(强缓存、协商缓存)
- 15、前端安全(XSS、CSRF)
- 16、localhost和127.0.0.1和0.0.0.0区别
- 17、https和http区别
- 18、传输安全
- 18、SSL三次握手(生成2+1个随机数)、数字证书校验
- 19、当你在浏览器中输入 url 并且按下回车之后发生了什么?
- 20、短轮询,长轮询,长连接
- 21、TCP如何保持长连接、http的keep-alive
参考文献
TCP为啥要3次握手和4次挥手?握两次手不行吗?【前端大全】
面试常问!!TCP的三次握手与四次挥手理解
【漫画】TCP连接为什么是三次握手,而不是两次握手,也不是四次握手?
1、握手一些概念
序列号seq(Sequence Number):
占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
确认号ack(Acknowledgment Number):
占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。
确认ACK:
占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
同步SYN:
连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
终止FIN:
用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
注意:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。
2、三次握手过程理解(2+4+2)
第一次握手
客户端向服务器发送连接请求报文,这时报文首部中的同步位SYN=1
,同时随机生成初识序列号seq=x
,此时TCP客户端进程进入了同步已发送
状态。注意:TCP规定,SYN报文段(建立连接)不能携带数据,但需要消耗掉一个序号。这个三次握手的开始,表示客户端想要和服务端建立连接。
第二次握手
TCP服务器收到客户端的请求后,如果同意连接,则发出确认报文。确认报文中应该ACK=1,SYN=1
,确认号是ack=x+1
,同时也要为自己初始化一个序列号seq=y
。此时,TCP服务器进入同步收到
状态。这个报文段也不能携带数据,但同样要消耗掉一个序号。这个报文带有SYN(建立连接)和ACK(确认)标志,询问客户端是否准备好
第三次握手
TCP客户端收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1
,此时,TCP连接建立,客户端进入已建立连接
状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。这里客户端表示我已经准备好了。
问1:为什么要三次握手,两次不就行吗
- 客户端确保了服务器的接受发送没问题,但是服务器仅仅只知道客户端的发送消息没问题,这并不是可靠的,所以两次握手不不能保证双方都知道对方都有发送和接收信息的能力。
- 根本原因: 无法确认客户端的接收能力。
分析如下:
如果是两次,客户端现在发了 SYN 报文想握手,由于网络延迟,但是这个包滞留在了当前的网络中迟迟没有到达,TCP 以为这是丢了包,于是重传,两次握手建立好了连接。
看似没有问题,但是连接关闭后,如果这个滞留在网路中的包到达了服务端呢?这时候由于是两次握手,服务端只要接收到然后发送相应的数据包,就默认建立连接,但是现在客户端已经断开了。这就带来了连接资源的浪费。
问2:三次握手过程中可以携带数据么?
第三次握手的时候,可以携带。前两次握手不能携带数据。
如果前两次握手能够携带数据,那么一旦有人想攻击服务器,那么他只需要在第一次握手中的 SYN 报文中放大量数据,那么服务器势必会消耗更多的时间和内存空间去处理这些数据,增大了服务器被攻击的风险。(DDOS攻击)
第三次握手的时候,客户端已经处于ESTABLISHED(已建立连接)状态,并且已经能够确认服务器的接收、发送能力正常,这个时候相对安全了,可以携带数据。
问3:第三次握手失败后
当A与B的第三次握手失败后,B在等待A回复ACK的过程中超时了,那么B会向A发送一个RTS报文并进入关闭状态。并不等待A第三次握手的ACK包重传,直接关闭链接
原因:为了防止泛洪攻击:即攻击者伪造许多IP向B发送请求,从而将B的未连接队列塞满,浪费B的资源
3、TCP四次挥手(2+3+4+2)
第一次挥手
TCP发送一个FIN(结束)
,用来关闭客户到服务器端的连接。客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1
,其序列号为seq=u
(等于前面已经传送过来数据的最后一个字节序号加1),此时客户端进入终止等待1
状态。TCP规定,FIN报文即使不携带数据,也要消耗一个序号。
第二次挥手
服务端接收到这个FIN,他发回一个ACK(确认)
,确认收到序号为收到序号+1,和SYN一样,一个FIN将占用一个序号。服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1
,并且带上自己的序列号seq=v
,此时服务端就进入关闭等待
状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候TCP连接处于半关闭
状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个关闭等待
状态持续的时间。客户端收到服务器的确认请求后,此时,客户端就进入终止等待2
状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
第三次挥手
若服务端已经没有要向客户端发送的数据,服务端应用程序就通知TCP可以释放连接了。这时服务端发送一个FIN(结束)到客户端,服务端关闭客户端的连接。此时FIN=1,ack=u+1
,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w
,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
第四次挥手
客户端发送ACK(确认)报文确认,并将确认的序号+1,这样关闭完成。
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1
,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。
注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)
的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
问:为什么是4次挥手呢?
为了确保数据能够完成传输。
关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必会马上关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
问:等待2MSL原因
- 第一,为了保证客户端发送的最后一个
ACK(确认)
报文段能够达到服务端。ACK报文段发送过程中有可能丢失,因而使处在最后确认
状态的服务端收不到这个确认报文段,这时服务端会超时重新传这个FIN+ACK
报文段,而客户端就能在2MSL
时间内收到服务端重传的FIN+ACK
报文段。接着客户端就会重传一次确认报文段,重新启动2MSL计时器。最后客户端和服务端都能进入到关闭状态。 - 第二,保证在本连接持续的时间内所产生的所有报文段失效。
4、TCP和UDP区别
-
连接与无连接;UDP是无连接的,即发送数据之前不需要建立连接;TCP是需要建立连接的(即握手挥手)
-
可靠性:TCP提供可靠的服务(流量控制-滑动窗口,无差错-确认重传,seq ack-保证顺序,拥塞控制),无差错,不丢失,不重复。UDP尽最大努力交付,不可靠
-
开销:(TCP20个字节,UDP8个字节)TCP对系统资源要求较多,UDP对系统资源要求较少(因为不用连接)。
-
每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信(直播)。
-
传输方式:TCP面向字节流,会进行一些分片操作,而UDP面向报文,只会在外面封装一层
-
应用:UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。(如直播、视频会议等);TCP则适用于要求可靠传输的应用,例如文件传输
5、如何实现UDP可靠传输
《UDP如何实现可靠传输》
在应用层模仿传输层TCP的可靠性传输:
- 添加
seq
/ack
机制,确保数据发送到对端 - 添加发送和接收缓冲区,主要是用户超时重传。
- 添加超时重传机制。
送端发送数据时,生成一个随机seq=x,然后每一片按照数据大小分配seq。数据到达接收端后接收端放入缓存,并发送一个ack=x的包,表示对方已经收到了数据。发送端收到了ack包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据。
目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。
6、TCP拥塞控制、流量控制
1、拥塞控制
机制:
主要是根据网络中的拥塞情况来控制发送方数据的发送速率,如果网络处于拥塞的状态,发送方就减小发送的 速率,这样一方面是为了避免继续增加网络中的拥塞程度,另一方面也是为了避免网络拥塞可能造成的报文段丢失
2、流量控制
机制:
这个服务的主要目的是控制发送方的发送速率,保证接收方来得及接收。因为一旦发送的速率大 于接收方所能接收的速率,就会造成报文段的丢失。接收方主要是通过接收窗口来告诉发送方自己所能接收的大小,发送方根据 接收方的接收窗口的大小来调整发送窗口的大小,以此来达到控制发送速率的目的。
为什么TCP不适用于实时传输?(拥塞控制、流量控制)
TCP影响实时性不是因为握手消耗时间。握手一开始建立完就没事了
一般来说,单位时间内传输的数据流量比较平滑。 TCP依赖滑动窗口进行流量控制,滑动窗口大小是自适应的,影响滑动窗口主要有两个因素,一是网络延时
,二是传输速率
,滑动窗口的大小与延时成正比,与传输速率也成正比。在给定的网络环境下,延时可以认为是固定的,因此滑动窗口仅与传输速率有关,当传输实时数据时,因为数据流通量比较固定,所以这时TCP上的滑动窗口会处于一个不大不小的固定值,这个值大小恰好保证当前生产的数据实时传输到对方,当出现网络丢包时,按TCP协议(快速恢复),滑动窗口将减少到原来的一半,因此速率立刻减半,此时发送速率将小于数据生产速率,一些数据将滞留在发送端,然后滑动窗口将不断增大,直到积累的数据全部发送完毕。上述过程即为典型的TCP流量抖动
过程,对于实时传输影响很大,可能形成较大的突发时延,从用户感观角度来说,就是有时比较流畅,但有时卡(抖一下
,并且比较严重),因此实时传输通常不使用TCP。
5、TCP 滑动窗口和流量控制
神三元大佬
对于发送端和接收端而言,TCP 需要把发送的数据放到发送缓存区, 将接收的数据放到接收缓存区。
而流量控制索要做的事情,就是在通过接收缓存区的大小,控制发送端的发送。如果对方的接收缓存区满了,就不能再继续发送了。
TCP 滑动窗口分为两种:
- 发送窗口
- 接收窗口。
发送窗口:
其中包含四大部分:
- 已发送且已确认
- 已发送但未确认
- 未发送但可以发送
- 未发送也不可以发送
发送窗口就是图中被框住的范围。SND 即send
, WND 即window
, UNA 即unacknowledged
, 表示未被确认,NXT 即next, 表示下一个发送的位置。
接收窗口:
REV 即 receive
,NXT 表示下一个接收的位置,WND 表示接收窗口大小。
6、CDN
CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,解决网络拥挤的状况,提高用户访问网站的响应速度。CDN的关键技术主要有内容存储和分发技术。
CDN基本原理
《从网购/直播入手理解什么是CDN》 、《web前端性能优化之CDN》、《知乎:CDN》
传统访问:
- 用户在浏览器输入域名发起请求
- DNS 服务器解析域名获取服务器 IP 地址
- 向该IP对应的服务器发送访问请求
- 服务器响应并返回数据
cdn访问:
- 在浏览器输入域名发起请求(源站域名)
- 经过本地DNS系统解析,DNS系统最终会将域名的解析权交给对应
CNMAE
域名指向的CDN专用DNS服务器(CNAME为CDN服务商域名,比如阿里云的cdn,在自己配置cdn的时候有。手动ping 需要cdn加速的域名(即源站),会发生转到CANME的地址
) - 然后得到全局负载均衡设备的IP地址
- 用户向全局负载均衡设备发送内容访问请求
- 全局负载均衡设备将实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息把最优的
服务节点
(缓存服务器)IP
地址返回给用户 - 用户向缓存服务器发起请求,缓存服务器将用户所需内容返回
- 用户就可以就近取得所需内容
- 如果这台缓存服务器上并没有用户想要的内容,而负载均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器(如果我们自己配置,源服务器就是我们一开始使用的服务器)将内容拉取到本地。
总结一下CDN的工作原理:通过权威DNS服务器来实现最优节点的选择,通过缓存来减少源站的压力。 其实cdn主要是干两件事:一是让用户访问最近的节点,二是从缓存或者源站获取资源
cdn应用场景(性能优化)
- 静态网页
- 大文件下载:软件下载,视频点播、图片、css、js文件
- 动态加速:直播网站
- 应用加速
CDN好处:
说了这么多,如果只是为了加速网站的访问速度,完全可以选择其他方式,为什么一定要用 CDN 呢?或者说,除了可以加速,CDN 还有什么好处?
- 有利于搜索排名。谷歌等搜索引擎已经把网站访问速度作为一个结果排名的重要指标了。
- 网站不容易宕机。其实这就和把鸡蛋放在很多篮子里是一个道理,多个服务器分流之后,源站的压力就会小很多。
- 减少托管成本。大多数服务器的带宽都是有限制的,分流之后不同的文件被存放在不同的服务器上,可以减少带宽产生的费用。
CDN缺点:
- 成本
- 服务地点:受众群体位于CDN没有服务器的国家/地区,则您网站上的数据可能需要比不使用任何CDN更进一步
- 安全性:需要借助第三方公司,第三方会收到有关您的网站和系统的信息
哪些情况不适用于CDN:
- 适度的用户人群:针对性、特定性、服务少数用户
- 极端本地化用户群:给定地理区域、本地化
- 监管和复杂的治理要求:用户数据敏感、数据管辖范围限制
7、dns解析方式:递归 迭代
DNS解析流程(默认递归):
- 浏览器输入域名,进行dns解析
- 首先先检查自己本地的
hosts
文件是否有缓存,没有则查找本地DNS解析器缓存 - 以上没有的话向本地配置的DNS服务器查找,没有的话则向根DNS服务器获取顶级域名服务器
- 本地dns服务器请求顶级域名服务器返回二级域名服务器
- 最后本地dns服务器请求二级域名返回权威域名服务器
- 权威域名服务器返回最终的ip地址给本地dns服务器,最后再返回给客户端
解析方式:
- 递归:A发送请求给B,B没有结果的话,B会去请求其他,直至返回结果
- 迭代:B发送请求给C,C没有结果,但给出了一个方向D,B继续发送请求给D,直至查询到结果
一般我们向本地 DNS 服务器发送请求的方式就是递归查询,因为我们只需要发出一次请求,然后本地 DNS 服务器返回给我 们最终的请求结果。而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程,因为每一次域名服务器只返回单次 查询的结果,下一级的查询由本地 DNS 服务器自己进行。
递归(默认的方式):
迭代:
8、HTTP常用的状态码
《问十:说说常见HTTP状态码?》、《http 301、302、304、400、405、415状态码》
1XX 信息:收到请求,继续处理(post请求)
2XX 成功:请求已成功接收,理解和接受
3XX 重定向:需要采取进一步措施才能完成请求,和响应头location
字段相关
4XX 客户端错误:请求包含错误的语法或无法满足
5XX 服务器错误:服务器无法满足明显有效的请求
- 200 请求成功或者强缓存
- 202 服务器端已经收到请求消息,但是尚未进行处理
- 301 永久转移(重定向)
- 302 临时转移(未login时候无法访问内容页 做一个临时重定向)
- 304 协商缓存(请求的资源伟修改)
- 400 bad request 请求报文中存在语法错误。比如参数没传对等问题
- 401:
unauthorized
未经授权,即请求要求身份验证。比如未登陆就操作页面,后端就会返回401告诉用户需要进行登录 - 403 Forbidden :请求被拒绝。
- 404 找不到该资源
- 405 method not allowed, 请求的方式(get、post、delete)方法与后台规定的方式不符合
- 500 服务端错误
- 503:由于临时的服务器维护或者过载,服务器当前无法处理请求。通常,这个是暂时状态,一段时间会恢复
9、TCP\IP协议族各层有什么作用
- 应用层:应用程序间沟通的层,如
http
、简单电子邮件传输(SMTP
)、文件传输协议(FTP
)、网络远程访问协议(Telnet
)等。 - 传输层:确保“报文”无差错、有序、不丢失、无重复地传输,主要功能是数据格式化、数据确认和丢失重传等。如传输控制协议(
TCP
)、用户数据报协议(UDP
)。 - 网络层:负责提供基本的
数据包
传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),即不负责丢失重传,如网际协议(IP
)。 - 网络接口层:物理传输通道,可使用多种传输介质传输,可建立在任何物理传输网上。比如光纤、双绞线等
10、HTTP1.0 HTTP 1.1 HTTP 2.0主要区别
HTTP1.0 HTTP 1.1 HTTP 2.0主要区别 、HTTP1.0、HTTP1.1 和 HTTP2.0 的区别
http1.1 相对于 http1.0 有这样几个区别:
连接方面
的区别,http1.1 默认使用持久连接Connection
(HTTP1.0的Keep-Alive
和HTTP1.1的persistent
),而 http1.0 默认使用非持久连接。http1.1 通过使用持久连接来使多个 http 请求复用同一个 TCP 连接,以此来避免使用非持久连接时每次需要建立连接的时延。目前对于同一个域,大多数浏览器支持 同时建立 6 个持久连接。资源请求方面
的区别,在 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 等更多可供选择的缓存头来控制缓存策略。- http1.1 中还新增了
host
字段,用来指定服务器的域名。http1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机 ,并且它们共享一个IP地址。因此有了 host 字段,就可以将请求发往同一台服务器上的不同网站。 - http1.1 相对于 http1.0 还新增了很多
方法
,如 PUT、HEAD、OPTIONS 等。
http2对比http1.1
二进制协议
:http2采用二进制的传输协议,而http1.1则采用文本传输;二进制格式传输效率比文本快的多多路复用
:(解决队头阻塞)以chrome为例,http1.1的并发请求数量最大是6(同一域名下),超出的并发请求必须等待;http2允许同一个TCP连接中可以同时发送多个请求而不会阻塞- 头部
header
压缩:对消息头采用Hpack进行压缩传输,能够节省消息头占用的网络流量,http1.1每次请求,都会携带大量冗余的头信息,浪费了很多宽带资源。(encoder) 服务端push
:它允许 Web 服务器在收到浏览器的请求之前提前发送一些资源给客户端
队头阻塞
浅析HTTP/2的多路复用
HTTP1.1管道化:
HTTP/1.1 默认使用了持久连接,多个请求可以复用同一个 TCP 连接,但是在同一个 TCP 连接里面,数据请求的通信次序 是固定的。服务器只有处理完一个请求的响应后,才会进行下一个请求的处理
如果前面请求的响应特别慢的话,就会造成许 多请求排队等待的情况,这种情况被称为“队头堵塞”。队头阻塞会导致持久连接在达到最大数量时,剩余的资源需要等待其他 资源请求完成后才能发起请求。
http2.0的多路复用
来解决:
HTTP2不使用管道化的方式,而是引入了帧
、消息和数据流
等概念,每个请求/响应被称为消息,每个消息都被拆分成若干个帧进行传输,每个帧都分配一个序号
。每个帧在传输时属于一个数据流,而一个连接上可以存在多个流,各个帧在流和连接上独立传输,到达之后在组装成消息,这样就避免了请求/响应阻塞。
这就是我们对网站优化时,使用雪碧图、合并脚本的 原因。
11、http的常用方法
方法 | 作用 |
---|---|
get | 用来请求URL指定的资源,只是请求资源,不对数据产生影响;请求是可以被浏览器缓存的;不安全 |
head | HEAD方法与GET方法相同,但没有响应体,仅传输状态行和标题部分(报文首部 )常被用于客户端查看服务器的性能 |
post | 用于将数据发送到服务器以创建 新资源或修改 现有资源;不会被浏览器缓存 |
put | 通过该方法客户端可以将指定资源的最新数据 传送给服务器取代 指定的资源的内容。 |
delete | 用来删除指定的资源,它会删除 URI给出的目标资源的所有当前内容。 |
connet | 要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL和TSL协议把通信内容加密后经网络隧道传输。 |
options | 用来查询针对请求URL指定的资源支持的http方法 。一般也是用于客户端查看服务器的性能 |
trace | 让Web服务器端将之前的请求通信环回给客户端方法。客户端可以用TRACE方法查询发送出去的请求时怎样被加工修改的。不常用,还容易引发XST攻击 |
http 请求方法 options 方法有什么用?
OPTIONS
请求与HEAD
类似,一般也是用于客户端查看服务器的性能。这个方法会请求服务器返回该资源所支持的所有 HTTP 请求方法,该方法会用’*'来代替资源名称,向服务器发送 OPTIONS 请求,可以测试服务器功能是否正常。JS 的XMLHttpRequest
对象进行 CORS
跨域资源共享时,对于复杂请求,就是使用 OPTIONS 方法发送嗅探请求,以判断是否有对指定资源的访问权限。
幂等性:HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用
具有幂等性:GET、DELETE、PUT
不具有幂等性:POST
POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles的语义是在http://www.forum.com/articles下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。而PUT所对应的URI是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性
区别 | get | post |
---|---|---|
数据传输上 | 通过拼接url | 通过request body体 |
url可见性 | 参数url可见 | url参数不可见 |
安全性 | 参数暴露不安全 | 相对安全点 |
缓存性 | 请求可缓存 | 请求不可缓存 |
后退页面的反应 | 请求页面后退时,不产生影响 | 请求页面后退时,会重新提交请求 |
传输数据的大小 | 一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大) | 根据php.ini 配置文件设定,也可以无限大。 |
参数的数据类型 | 只接受ASCLL字符 | 无限制 |
数据包 | 产生一个数据包(直接发送) | 产生两个数据包(先发送header 响应100 continue,再发送data 响应200 OK) |
- url可见性:get,参数url可见;post,url参数不可见
- GET参数直接暴露在URL POST则在request body
- 缓存性:get请求是可以缓存的;post请求不可以缓存
get
请求类似于查找的过程,用户获取数据,不会对服务器资源数据造成修改,所以可以使用缓存。
post
不同,post 做的一般是修改和删除的工作,一般都会对服务器数据造成修改,所以不能使用缓存。因此 get 请求适合于请求缓存。
- GET产生一个数据包(直接发送), POST产生两个数据包(先发送header 响应100 continue ,再发送data 响应200 ok)
- GET POST的语义化区别
12、http持久连接
HTTP之持久连接
Http长连接、短连接、持久连接这三个概念的分析总结
13、http报文首部
图解http(03)-http首部
请求报文:
一个HTTP请求报文由请求行(request line)、请求头部(request header)、空行和请求数据4个部分构成。
http请求报文头部 = 请求行 + http请求头(头部字段)
http请求头部字段:
- 请求首部字段:从客户端向服务器发送请求报文时使用的首部;
- 通用首部字段:请求报文和响应报文都使用的字段;
- 实体首部字段:针对请求报文和响应报文的实体部分使用的首部
POST /search HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-silverlight, application/x-shockwave-flash,
Referer: http://www.google.cn/
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
Host: www.google.cn
Connection: Keep-Alive
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r
hl=zh-CN&source=hp&q=domety
响应报文:
响应报文结构与请求报文结构唯一的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。
http响应报文头部 = 状态行 + http响应头(头部字段)
http响应头部字段:
- 响应首部字段:从服务器向客户端返回响应报文时使用的首部;
- 通用首部字段:请求报文和响应报文都使用的字段;
- 实体首部字段:针对请求报文和响应报文的实体部分使用的首部
请求首部字段:从客户端向服务器发送请求报文时使用的首部;
Accept
:首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的优先级,type/subtype。- Accept-Charset:通知服务器用户代理支持的字符集及字符集的相对优先级顺序。 Accept-Charset: iso-8859-5, unicode-1-1
Accept-Encoding
:通知服务器用户代理支持的内容编码及内容编码的优先级gzip
代码压缩优化- Accept-Language:通知服务器用户代理能够处理的语言及相对优先级。
- Authorization:客户端和源服务器之间的认证信息。 Authorization: Basic dWVub3N1bjpwYXNzd29yZA==
Host
:Host会告知服务器,请求的资源所处的服务器主机名和端口号。(正对虚拟主机的出现) Host: www.hackr.jp- If-Modified-Since:如果资源在指定日期之后更新过则服务器执行客户端请求,如果在这之后资源没有更新过返回状态码304
- Referer:告诉服务器请求是从哪里发出的。
- User-Agent:用于传达浏览器的种类。
响应首部字段:从服务器向客户端返回响应报文时使用的首部;
- Age:告诉客户端服务器在多久前创建了响应。
- ETag:对服务器端资源的唯一标记方式,服务器会为每份资源分配对应的ETag值。当资源更新时ETag值也会改变。
Location
:用来告诉客户端访问的资源已经被转移到了该值的下面,会返回3XX重定向的状态码。- Server:告诉客户端当前服务器上安装的HTTP服务器应用程序的信息。
通用首部字段:请求报文和响应报文都使用的字段;
Cache-Control
:和缓存相关的指令,可以多个参数用,
分隔: Cache-Control:private, max-age=0, no-cacheConnection
:一是控制代理不再转发首部字段,二是持久连接管理(Keep-Alive、false)- Date:表示创建报文的日期和时间。
- Pragma:是为了兼容Http版本而存在
- Transfer-Encoding:规定传输报文主体时用的编码格式,chunked表示分块传输
实体首部字段
- Allow:客户端通过OPTIONS方法来询问服务器支持哪些方法,服务器通过Allow返回是否支持该方法。如果支持该方法直接返回该方法,如果不支持,则返回状态吗405且将支持的所有方法返回
Content-Encoding
:会告知客户端服务器对实体的主体部分选用的内容编码方式。- Content-Type:说明了实体主体的类型,类型和请求首部字段Accept一致
- Last-Modified:资源最终修改时间。
Content-Type
告知对方用的编码方式,然后对应去解码读取数据文件
application/x-www-form-urlencoded
浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。该种方式提交的数据放在 body 里面,数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL转码。multipart/form-data
该种方式也是一个常见的 POST 提交方式,通常表单上传文件时使用该种方式application/json
(目前最常用的)
告诉服务器消息主体是序列化后的 JSON 字符串text/xml
该种方式主要用来提交 XML 格式的数据。
14、前端缓存(强缓存、协商缓存)
浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
(1)强缓存(不用发起请求):
命中 200
存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果
Expires
: Wed, 11 May 2018 07:20:00 GMT, http1.0 绝对时间Cache-Control: max-age=315360000
http1.1相对时间 【避免客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差】- no-cache :强制每次请求直接发送给源服务器,即是否使用缓存则需要访问服务器经过协商缓存来验证决定
- no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
- public:所有内容都将被缓存(客户端和代理服务器都可缓存)
- private :所有内容只有客户端可以缓存,Cache-Control的默认取值
s-maxage
:代理服务器(中转服务器,有点类似于cdn边缘服务器)缓存,减轻源站服务器压力,加快访问速度《缓存代理》
注:Cache-Control的优先级比expires高
(2)协商缓存(要发起请求):
命中304
存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存,携带该资源的缓存标识发起http请求。
1、Last-Modified
和If-Modified-Since
:
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间,浏览器会在request header加上If-Modified-Since
(上次response header返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,没变化则返回请求头304,有变化则重新从服务器获取内容,成功的话返回200和内容。
不足之处:
- 一些文件也许会周期性的更改(定时重新生成相同内容),但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
- Last-Modified只能精确到秒(比方文件说1s内修改了N次,这种修改无法检测)
2、 HTTP / 1.1 出现了 ETag
和If-None-Match
ETag
就像一个指纹,资源变化都会导致ETag变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的- 包含有
If-None-Match
的request header会将上次response header返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变动则重新从服务器获取内容
注:Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。
操作 | 强缓存 | 协商缓存 | 原因 |
---|---|---|---|
F5刷新 | 缓存无效 | 缓存有效 | F5刷新请求头中通常包含了If-Modified-Since 或If-None-Match 字段 |
Ctrl + F5 强制刷 | 缓存无效 | 缓存无效 | Ctrl + F5 强制刷请求头中没有上面的那两个字段,却有Pragma: no-cache 或 Cache-Control: no-cache 字段,即不使用缓存 |
15、前端安全(XSS、CSRF)
(1)XSS(跨站脚本攻击)
XSS 跨站脚本攻击(Cross Site Scripting)简单点来说,就是攻击者想尽一切办法将可以执行的代码注入到网页中。
类型:
- 持久型(存储型):就是攻击的脚本代码被服务端写入进数据库中,这种攻击危害性很大(评论功能)
- 非持久型(反射型):一般是将脚本代码拼接到
URL
请求参数里,页面需要从 URL 中获取某些参数显示出来
只有Chrome 浏览器能自动帮助用户防御攻击, 很贴心
防御对策:
- 转义字符:对于用户的输入应该是永远不信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义
- CSP(Content Security Policy): 本质上就是建立白名单,在http头部设置
Content-Security-Policy
指定那些内容可加载或设置meta
标签的方式
(2)CSRF(获取用户身份cookie)
跨站请求伪造,原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。(银行钓鱼网站)
防御对策:
防范 CSRF 攻击可以遵循以下几种规则:
- get请求不对数据进行修改
- cookie同源,不让第三方网站访问到用户cookie:对 Cookie 设置
SameSite
属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。 - 阻止第三方网站请求接口:通过判断http请求header中
Origin
(只包含域名信息)和referer
(包含具体路径)(不过这两者都可以自定义请求头伪造) - 请求时附带验证信息,比如验证码或者
token
:服务器下发一个随机 Token,每次发起请求时将 Token 携带上,服务器验证 Token 是否有效
(3)sql注入
后台人员使用用户输入的数据来组装SQL查询语句的时候不做防范(比如说登陆验证)
需要进行 过滤
和 验证
机制
(4)点击劫持(iframe视觉欺骗)
攻击方式就是在某些操作的按钮上加一层透明的iframe,诱导用户点击
防御:
- 推荐:
X-FRAME-OPTIONS
禁止内嵌(IE8以上) 服务器返回html页面的时候,设置X-Frame-Options: DENY,浏览器就会阻止嵌入网页的渲染。 - 目标网站JS禁止内嵌
- 目标网站前端使用js: top(顶层环境) == window(当前环境)
- 相等则表示目标网站在顶层
- 不等则表示目标网站被iframe内嵌 使用top.location跳转到window.loacation
缺点:攻击者网站禁用目标网站js =>sandbox=”allow-forms”
(5)中间人攻击(拦截网络通信数据)
攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息
防御:
- 使用
https
协议 - 不要在公共
Wi-Fi
上发送敏感数据
(6)DDOS
发送大量请求是使服务器瘫痪。DDos攻击是在DOS攻击基础上的,可以通俗理解,dos是单挑,而ddos是群殴,
16、localhost和127.0.0.1和0.0.0.0区别
localhost、127.0.0.1和0.0.0.0和本机IP的区别
localhost | 127.0.0.1 |
---|---|
域名 | ip地址 |
不通过网卡传输,不受网络防火墙和网卡相关的限制。 | 通过网卡传输,依赖网卡,并受到网卡和防火墙相关的限制 |
localhost访问时,系统带着本机当前的用户权限去访问 | 用ip的时候,等于本机是通过网络再去访问本机 |
localhost
其实是域名,一般windows系统默认将localhost指向127.0.0.1,但是localhost并不等于127.0.0.1,localhost指向的IP地址是可以配置的(在hosts
文件里配置)
凡是以127
开头的IP地址,都是回环地址(Loop back address),意思就是我们在主机上发送给127开头的IP地址的数据包会被发送的主机自己接收,根本传不出去
0.0.0.0用途
- 当一台主机还没有被分配一个IP地址的时候,用于表示主机本身
- 用作默认路由,表示”任意IPV4主机”
- 用来表示目标机器不可用
- 用作服务端,表示本机上的任意IPV4地址
17、https和http区别
- https需要到
ca
(数字证书颁发机构)申请证书(这套数字证书其实就是一对公钥和私钥,私钥存放在服务端,公钥发给客户端用),一般都要钱 - http是超文本传输协议,信息是明文传输。https在http基础上加了ssl(Secure Sockets Layer)协议,因此是加密传输
- http和https连接方式不同,用的端口不一样,http是80,https是443
- http连接无状态,https可进行身份验证
18、传输安全
《一文看懂https如何保证数据传输的安全性的》、《HTTPS加密原理》
- AES、DES对称加密(双方都有一个共同的密钥,然后通过这个密钥完成加密和解密,这种加密方式速度快,但密钥容易被获取)
encrypt(明文,秘钥) = 密文
decrypt(密文,秘钥) = 明文
- RSA非对称加密:有两把密钥,公钥和私钥。私钥只有服务端知道,公钥可以公开给别人(安全,但加密时需要经过大量的计算,消耗计算机资源)
encrypt(明文,公钥) = 密文
decrypt(密文,私钥) = 明文
- 对称+非对称结合:使用非对称加密对密钥进行加密,使用对称加密对传输数据加密(无法认证公钥是来自服务端还是中间人,有可能受到中间人攻击)
- 信任机制: https、CA 证书(能证明这把公钥就是服务器的,而不是中间人冒充的)
18、SSL三次握手(生成2+1个随机数)、数字证书校验
客户端A,服务端B(A、B都知道这个证书)、非对称加密 + 对称加密 + CA验证
确保传输密钥是来着服务器而非中间人,并且保证了传输速率。
- A向B发送自己的
SSL/TLS
协议版本、加密方式(不同版本或不同加密方式无法连接)以及A生成的随机数x
- B确认使用的加密方式,并向A发送数字证书(公钥)、B生成的随机数
y
- 接着A校验数字证书有效性(
ca
信任),生成随机数z,并使用收到的数字证书公钥,加密这个随机数z
,发送给b - B使用数字证书中的私钥,解密出随机数z
- AB根据x、y、z生成对话密钥session key ,来加密解密接下来的对话(这时就是利用
对称加密
了)
CA 数字证书内一般会包含以下内容:
- 证书的颁发机构、版本
- 证书的使用者
- 证书的公钥
- 证书的有效时间
- 证书的数字
签名
Hash 值和签名Hash 算法
客户端如何校验 CA 证书有效性:
CA 证书中的 Hash 值,其实是用证书的私钥进行加密后的签名(证书的私钥不在 CA 证书中)。客户端得到证书后,利用证书中的公钥去解密该 签名,得到信息摘要 Hash-a
;然后再利用证书内的 Hash 算法去生成一个信息摘要 Hash-b
。最后比较l两个摘要Hash-a
和 Hash-b
这两个的值。如果相等,那么证明了该证书是对的,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,可能被篡改了,浏览器会给出相关提示,无法建立起 HTTPS 连接。除此之外,还会校验 CA 证书的有效时间和域名匹配等
19、当你在浏览器中输入 url 并且按下回车之后发生了什么?
(1)浏览器输入域名访问
(2)浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。(强缓存)
(3)DNS解析(默认递归):
- 首先先检查自己本地的
hosts
文件是否有缓存,没有则查找本地DNS解析器缓存 - 以上没有的话向本地配置的DNS服务器查找,没有的话则向根DNS服务器获取顶级域名服务器
- 本地dns服务器请求顶级域名服务器返回二级域名服务器
- 最后本地dns服务器请求二级域名返回权威域名服务器
- 权威域名服务器返回最终的ip地址给本地dns服务器,最后再返回给客户端
(4)TCP三次握手,如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个三次握手的过程
(5)客户端请求发送到服务器端
(6)服务器端返回请求的文件(首次返回通常是HTML文件)
(7)浏览器渲染:
1、 将HTML
字节流解析成 DOM Tree
- 词法分析:把字符流(HTML其实是一坨字符串)初步解析成我们可理解的"词",学名叫token(一个数组,有点像
babel
转化) - 语法分析:将 Token 解析为 DOM 节点(把开始结束标签配对、属性赋值好、父子关系连接好、构成dom树)(利用了栈数据结构)
2、同时将 CSS
解析成CSSOM Tree
(不冲突)
3、将 DOM Tree
和 CSSOM Tree
合并成Render Tree
4、生成布局Layout
,计算Render Tree
中各节点元素的尺寸、位置(自动重排)
5、将Render Tree
绘制成像素点,调用由浏览器的UI组件的paint()
方法在屏幕上显示对应的内容
拓展:生成Render Tree
,也就是渲染树,其实这还是 16 年之前的事情,现在 Chrome 团队已经做了大量的重构,已经没有生成Render Tree的过程了。而布局树的信息已经非常完善,完全拥有Render Tree的功能
(8)响应完成之后,这时候要判断Connection
字段, 如果请求头或响应头中包含Connection: Keep-Alive
,表示建立了持久连接,这样TCP连接会保持,之后请求统一站点的资源会复用这个连接(保持的时间服务器可以设置),否则断开TCP连接, 请求-响应流程结束
20、短轮询,长轮询,长连接
(1)http传统轮询(短轮询)《Web通信中传统轮询、长轮询和WebSocket简介》
客户端定时向服务器发送请求,服务器接到请求后马上返回响应信息并关闭连接。
(2)长轮询
客户端向服务器发送请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接(或到了设定的超时时间关闭连接),客户端处理完响应信息后再向服务器发送新的请求。
- 优点:减少了很多不必要的http请求次数,相比之下节约了资源。
- 缺点:服务器hold连接会消耗资源,需要同时维护多个线程,服务器所能承载的TCP连接数是有上限的,这种轮询很容易把连接数顶满。
(3)http长连接
HTTP1.1通过使用Connection:keep-alive
进行长连接,HTTP 1.1默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发header
,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache、Linux)中设定这个时间。
(4)websocket
websocket的长连接,是一个真的全双工的Tcp长连接
。长连接第一次tcp链路建立之后,后续数据可以双方都进行发送,不需要发送请求头header
21、TCP如何保持长连接、http的keep-alive
《TCP如何保持长连接,并识别不同请求》、《TCP keepalive 和 http keep-alive》
- TCP长连接主要基于
保活计时器timeout
(这个具体值可以在服务器里面配置),每收到一次请求后就会复位这个计时器,如果计时器时间到期了,那么就会发送一个不包含数据部分的探测报文(心跳数据包
),只要另一方没有异常断开,那么一定会返回一个应答包,这时说明连接还不能断开,所以要保持连接。 - 而HTTP长连接以客户端向服务器发送请求为例,服务端响应头上有一个keep-alive,里面可以设置一个守护进程timeout,表示等待时间,如果在这个时间没有收到客户端发来的数据包,服务器就会关闭这个连接。长连接要求是设置了keep-alive的http请求都在一条tcp上,可以理解为客户端所有请求都在这条tcp上,timeout时间内服务器没有收到客户端请求,就会把连接关闭
timeout
的设置主要是为了避免客户端没有请求了,还要长时间保持连接,占用资源
区别:
- 两者在写法上不同,http keep-alive 中间有个"-"符号。
- HTTP协议的keep-alive 意图在于连接复用,同一个连接上串行方式传递请求-响应数据
- TCP的keepalive机制意图在于保活、心跳,检测连接错误。
http识别不同请求:
当每个连接建立后,都会保存唯一的套接字
,其中包含对端的IP地址、端口号等信息,这样通过这个套接字就会识别出来各种不同的请求,就可以向指定的对端发送信息了。