网络请求

442 阅读11分钟

HTTP HTTPS 网络请求

常见的HTTP状态码

  • 301 永久重定向
  • 302 临时重定向
  • 304 协商缓存
  • 403 没有权限访问

三次握手

第一次握手

客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。

第二次握手

服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。

第三次握手

当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。

明明二次握手就可以建立链接为什么要进行第三次握手

因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。

可以想象如下场景。客户端发送了一个连接请求 A,但是因为网络原因造成了超时,这时 TCP 会启动超时重传的机制再次发送一个连接请求 B。此时请求顺利到达服务端,服务端应答完就建立了请求,然后接收数据后释放了连接。

假设这时候连接请求 A 在两端关闭后终于抵达了服务端,那么此时服务端会认为客户端又需要建立 TCP 连接,从而应答了该请求并进入 ESTABLISHED 状态。但是客户端其实是 CLOSED 的状态,那么就会导致服务端一直等待,造成资源的浪费。

四次挥手(TCP是双向)

  • 客户端接收到了最终的数据,会想服务端发送断开链接的请求
  • 服务端收到请求,会告诉客户端释放请求,此时client -->> server的tcp链接关闭;
  • 服务端仍然可以给客户端发送请求,发送完毕之后想客户端发送释放链接的请求;
  • 客户端收到释放请求后,向B应答,B收到应答就会进入close,客户端会保持一段时间链接,这段时间内没有数据返回就会关闭链接;两端都会close;

TCP和UDP;

  • TCP是面向链接的,UDP是想发就发不需要
  • TCP传递数据保证了数据的可靠性准确性和时序;UDP传递的数据是不确定性的(有可能会丢包);
  • TCP只能1对1;UDP可以1V1,1对N;
  • TCP的首部较大为20字节,而UDP只有8字节。

HTTP2.0

  • 提升访问速度(可以对于,请求资源所需时间更少,访问速度更快,相比http1.0)
  • 允许多路复用:多路复用允许同时通过单一的HTTP/2连接发送多重请求-响应信息。改善了:在http1.1中,浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制(连接数量),超过限制会被阻塞。
  • 二进制分帧:HTTP2.0会将所有的传输信息分割为更小的信息或者帧,并对他们进行二进制编码
  • 首部压缩
  • 服务器端推送

什么是 XSS 攻击?如何防范 XSS 攻击?什么是 CSP?

XSS 就是攻击者想尽办法将可执行的代码放到你的页面中;

  • 持久性:攻击的代码注入到了数据库中
  • 非持久性:攻击的代码只有此次起到了作用

CSP是浏览器建立浏览器的白名单,告诉浏览器哪些域名下的资源可以加载执行;

打开方式:

  • 设置 HTTP Header 中的 Content-Security-Policy
  • 设置 meta 标签的方式

什么是 CSRF 攻击?如何防范 CSRF 攻击?

跨站信息伪造

防御方式:

  • Get 请求不对数据进行修改
  • 不让第三方网站访问到用户 Cookie
  • 阻止第三方网站请求接口
  • 请求时附带验证信息,比如验证码或者 Token
  • 验证 Referer;对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。

HTTPS是怎么加密

HTTPS

HTTP的队头阻塞

长连接

HTTP1.0和HTTP1.1最重要的区别就是HTTP1.1开启了长连接模式; 在HTTP1.0时开始数据传输数据传输的方式可以看成下边的方式:

HTT1.0建立链接

上图中可以看出每次传输数据都需要重新去建立TCP的链接;有多少个请求就要去建立多少个http的tcp链接;

在HTTP1.1之后增加了HTTP的长连接;请求的发起就可以看成下图:

HTTP1.1长连接

上图就是HTTP长连接的状态图,感觉叫做TCP长连接更合适;页面中的对于同一域名的请求只需要创建一次tcp链接,多个http请求会共用一个tcp链接;

此时http请求中会携带一个Http请求头:Connection:keep-alive,现在大部分的web服务器都默认支持tcp长连接,也就是网页中的请求不携带Connection:keep-alive请求头,默认就是长连接请求,如果不想支持长连接的话,需要显示的添加Connection:closed请求头。

长连接存在的弊端

一般的http请求都有需要遵守 请求-响应 的过程;就是客户端发送一个请求等待服务端返回数据才能进行下一次请求发送;(可以理解为多个请求是串行发送的),这时如果页面中存在多个请求;每个请求必须等到前一个请求响应完毕之后才能发送;这时候如果某一个请求发生了延时,导致后边的也发送不了,这时就造成了队头阻塞;

长连接队头阻塞

长连接管道模式

上边说明了多个请求是串行发送的;串行的效率是比较低的;为了提高效率和速度,长连接还可以开启管道模式;可以将请求的发送改成并行的;管道化允许客户端在已发送的请求收到服务端的响应之前发送下一个请求;如下图:

管道化长连接请求发送

上边图中可以看出:client并行发起多个请求,服务端收到请求就响应哪一个请求;客户端请求响应是按照接收到请求的顺序来的,先接收的先响应,后接收的后响应;这时候如果其中某一个响应出现了问题被阻塞了,后边接收到的响应必须等待,这时候也出现了队头阻塞;

管道模式的限制

  1. 因为HTTP的请求和响应是没有状态的,即使没有标识号来告知client这次请求的对应响应;所以如果开始管道模式服务端必须要保持响应的准确性;
  2. 客户端支持管道化是需要保持未收到响应的请求,如果意外中断是需要重试的,如果这个请求只是从服务器获取数据,那么并不会对资源造成任何影响,而如果是一个提交信息的请求如post请求,那么可能会造成资源多次提交从而改变资源,这是不允许的;

解决队头阻塞

  1. 并发长连接,浏览器默认是6-8个长连接,我们可以用域名分片的技术突破这个数值。
  2. http2.0的多路复用;

客户端建立长连接的个数是针对域名发起的,举例说明,当我们访问a.com网站的时候,客户端与a.com服务器建立的长链接就是2个;

这样你就知道为啥web的性能优化的时候;你虽然没做过但是你知道将不同的静态资源放到不同的域名下加载;因为可以突破这个并发长连接个数限制;

HTTP2.0的多路复用

多路复用基本概念

上边已经知道了http1.0的长连接模式,无论开不开管道模式,其实http1.0只实现了一个半双工的模式;就是只有cliet一端可以并行发起请求作另一端还是只能串行去响应;

HTTP2.0实现了全站双工模式;只建立了一次tcp链接,针对这个域名下的所有的请求都是通过这个链接来完成的;http2.0引入了流和帧的概念,使得通道可以同时发起多个请求并切可以不分先后的去响应请求;彻底解决了队头阻塞的问题;

HTTP2.0的传输方式

http1.1是明文协议,解析http1.1的明文是基于文本。http2.0的协议采用的是二进制格式

  1. http1.1是明文进行传输的,不安全,体积大,解析速度慢;
  2. 二进制格式只认识0和1解析速度快;

二进制分帧

将HTTP1.1的头部个body体转换成二进制的重要步骤;在传输层(TCP/UDP)和应用层(HTTP)之间住呢国家了二进制分针操作;

HTTP2.0的二进制分帧

  1. 在http是的构成中将加密层之上又多出了一层二进制分帧;
  2. 在二进制分帧层中,http2.0将http1.1的所有的传输信息分割成更小的帧,并进行二进制编码,图中可以看出http1.1的头部信息会被封装进入http2.0的header frame中;请求体信息会被封装进入http2.0的data frame中

上边介绍了,http2.0的请求和相应的信息是不分先后顺序的,但是客户端还是可以拿到对应的数据信息所有在二进制分帧中另一个操作是:

  1. 二进制分帧层虽然将一个请求分割成了好多帧,但是会为这些帧打上相同的唯一性标识,多个帧就会组成这一次的请求流,服务端会对这些唯一性标识归类形成的流进行响应,客户端就知道当前请求信息的相应数据;

浏览器的缓存

强缓存

强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control 。强缓存表示在缓存期间不需要请求,state code 为 200。

Expires

Expires: Wed, 22 Oct 2018 08:41:00 GMT

Expires 是 HTTP/1 的产物,表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

Cache-control

Cache-control: max-age=30

Cache-Control 出现于 HTTP/1.1,优先级高于 Expires 。该属性值表示资源会在 30 秒后过期,需要再次请求。

属性 解释
public 表示响应可以被client和proxy server缓存
private 响应只能被client缓存
max-age=30 缓存30s后过期
s-maxage=30 覆盖max-age但是只在proxy server中生效
no-store 不做任何缓存
no-cache 资源被缓存,但是立即失效,下次请求需要确认资源是否过期
max-stale=30 资源30秒内即使过期也使用缓存;
min-fresh=30 30秒内获取最新响应

协商缓存

当浏览器发起请求验证资源时,如果资源没有做改变,那么服务端就会返回 304 状态码,并且更新浏览器缓存有效期。如果缓存过期了,就需要发起请求验证资源是否有更新。

Last-Modified

Last-Modified 表示本地文件最后修改日期,If-Modified-Since 会将 Last-Modified 的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,否则返回 304 状态码。

但是 Last-Modified 存在一些弊端:

  1. 如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源
  2. 因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源

ETag

ETag 类似于文件指纹,If-None-Match 会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来