前端HTTP和HTTPS的基础知识

基本一些网络的基本知识

目录

  1. HTTP协议介绍
  2. HTTP各版本的差别
  3. HTTP协议三次握手四次挥手
  4. HTTPS握手过程
  5. HTTP状态码

HTTP协议介绍

HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程(当然不是只用于web,只是在浏览器的角度说而已)。客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用于定义客户端与web服务器通迅的格式。

http的请求方式共有8种。

  1. OPTIONS – 返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
  2. HEAD – 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。
  3. GET – 向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
  4. POST – 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
  5. PUT – 向指定资源位置上传其最新内容
  6. DELETE – 请求服务器删除Request-URL所标识的资源
  7. TRACE – 回显服务器收到的请求,主要用于测试或诊断
  8. CONNECT – HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

HTTP各版本的差别

我们现在基本上都是用1.0,1.1或者2.0的版本,所以更多去说明1.0,1.1和2.0之间的一些区别。

1.0与1.1的区别:

  1. http1.1默认开启keep-alive一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
  2. http1.1拥有更多的控制缓存的字段,1.0的时候一般使用If-Modified-Since,Expires来控制缓存,但是1.1提供了Entity tag,If-Unmodified-Since, If-Match, If-None-Match等来控制缓存。
  3. 带宽优化及网络连接的使用
  4. 错误通知的管理
  5. Host头处理

1.x和2.0的区别

  1. 多路复用
  2. 二进制分帧
  3. header压缩
  4. 服务端推送

这里先知道2.0新出了什么,我们后面在详细讨论2.0的一些新特性,以及在使用2.0的情况下前端的优化方案。

HTTP协议三次握手四次挥手

面试题经常会问,三次握手和四次挥手的问题,当然如果你靠背书的话,那么你也能一字不漏的说出整个流程,以及每次握手的时候和挥手的时候传输的包内容。但是设想以下场景:

  • 面试官:能描述以下三次握手和四次挥手的过程吗?
  • 你:因为………
  • 面试官:那你能说说为什么一定要三次握手,为什么要四次挥手吗,能不能两次握手,或者四次握手,能不能三次挥手?
  • 你:懵逼了…

我们除了知道握手和挥手的流程以外,我们还需要明白为什么要做么做。

三次握手图

用文字大概描述以下过程。

  1. 客户端发起请求,会想发送一个SYN包,里面包含SYN=1,seq=x(随机数)
  2. 服务器收到请求,识别这是一个SYN=1的包(客户端发起请求),服务器随后组装一个ACK包,里面包含SYN=1,ACK=1,ack=x+1(客户端发来的seq+1),seq=y(随机数)
  3. 客户端收到ACK包(服务器收到请求),首先会验证ack码是否是SYN包的seq+1的结果,如果符合,那么将会发送一个ACK包给服务器,里面包含ACK=1,ack=y+1
  4. 服务器收到ACK包后,验证ACK=1,并且ack码是服务器发送给客户端的ack码+1的结果。

这里只是回答了流程,但是为什么一定要三次握手呢?

这里就需要搞清楚客户端和服务器端通信必须要在双方的发送功能和接收功能都正常的情况下进行通信的,那么三次握手就是为了要确保双方的发送功能和接收功能都正常的握手次数。

  1. 第一次握手
    1. 客户端发送SYN包
    2. 服务器收到SYN包
  2. 第二次握手
    1. 服务器发送ACK包(服务器接收功能正常)
    2. 客户端收到ACK包(客户端确认发送和接收功能正常)
  3. 第三次握手
    1. 客户端发送ACK包
    2. 服务器接收ACK包(服务器发送功能正常)

如果判断发送和接收正常呢,就是靠ACK包里的seq进行+1来进行验证的。所以三次握手是最少的安全握手次数。

四次挥手图

流程大概和三次握手一样,只是这次不是SYN包,而是FIN包。

  1. 客户端发送FIN包,包含FIN=1,seq=x(随机数),发送FIN包后,客户端不能发送数据,但是能接受数据,等待关闭状态1
  2. 服务器收到FIN包,会返回一个ACK包,包含ACK=1,ack=x+1,发送ACK包后,服务器不能接受数据,但是能发送数据
  3. 客户端需要等待服务器返回FIN包
  4. 服务器发送FIN包,包含FIN=1,seq=y(随机数),发送FIN包后,等待客户端的ACK包。
  5. 客户端接受到服务器发送来的FIN包,然后发送一个ACK包,包含ACK=1,ack=y+1
  6. 客户端等待2MSL时间,然后关闭连接。
  7. 服务器收到客户端ACK包,然后关闭连接。

那么为什么一定要四次挥手呢?因为当客户端发送FIN包给服务器端的时候,服务器可能这个时候还有数据传输中,所以并不能像三次握手一样,将FIN包和ACK包信息一起发送给客户端,只能先告诉客户端,我收到你的FIN包。服务器将最后的数据发送完毕后,这时才会发送一个FIN包给客户端,客户端收到服务器的FIN包后才会真正进入关闭。同样,服务器收到客户端的ACK包后才会关闭。

那么为什么客户端收到了FIN包并且发送ACK包给服务器后不是立刻关闭,还需要等待2MSL呢?

  1. 所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。
  2. 为什么要等待2MSL是因为客户端接收到服务器的FIN包后发送ACK包,客户端并不能确保服务器收到ACK包,如果这时候服务器没有收到ACK包,那么服务器会在一段时间内重新发送FIN包给客户端,这时候客户端接收到FIN包,会从新发送ACK包给服务器,重新进行第四次握手。如果客户端等待时间超过2MSL,那么将会丢弃掉这个链接。

如果能理解我所说的原因,那你对于三次握手和四次握手的基本信息都能清楚明白了。

HTTPS握手过程

https为什么会有握手过程?在我们使用http的时候,我们只是使用tcp进行握手,然后就可以直接开始通信了,但是使用https却要在tcp握手链接成功后,还需要进行SSL/TLS协议进行握手。以下是基本的握手流程

  1. 客户端发出请求(ClientHello): 客户端向服务端发起加密通信的请求
  2. 服务器回应(SeverHello): 服务器收到客户端请求后,确认加密通信协议版本是否一致,如果版本一致则返回服务器证书,否则关闭加密通信
  3. 客户端回应:客户端收到服务器回应后,客户端首先验证证书是否有效。如果证书失效,则会给访问者一个警示,由其决定是否继续连接。如果证书没失效,则使用证书中的公钥加密一个随机数(pre-master key)返回给服务器,同时返回客户端握手结束通知。
  4. 服务器的最后回应:服务器收到客户端发来的pre-master key后,计算生成本次会话的“会话密钥”,向客户端发送服务器握手结束通知。

上面的流程是需要四次握手完成的。我理解为什么HTTPS需要这样的流程,我们首先需要搞明白HTTPS是为了解决什么问题的?

中间人攻击/网络劫持

举个简单的例子,我们的网页,如果使用http协议,那么有时候会被运行商劫持,注入运营商的广告等。这是因为我们使用http进行通信的时候,一切都是明文通信,那么途径运行商服务器时,就可以对我们传输的html或者js添加脚本从而达到插入广告的效果。再举一个严重的例子,例如用户与用户之间的通信信息或者密码等敏感信息如果被中间监听,那么后果可能会非常严重。所以就需要对http通信的报文进行加密。

  1. 使用对称加密:但是使用对称加密方式,就需要双方都知道秘钥,使用相同的秘钥进行加密和解密,但是这里就会有一个问题,就是秘钥的通信,客户端如何知道秘钥是什么呢?如果把秘钥写死在页面中,也是相当容易被破解,如果通过服务器提前将秘钥告知客户端,那么在秘钥的传输过程中,其实中间人也能获取到秘钥,那么加密就没有任何效果了,中间人依然能通过捕获到的秘钥对加密信息进行解密获取明文信息。
  2. 非对称加密:发送方使用公钥加密数据,接收方使用私钥解密数据,那么客户端就可以通过请求服务器端,获取服务器的公钥,进行对提交内容的加密,然后服务器用自己的私钥进行解密。但是这里也会有一个问题,就是如果中间人捕获到服务器的公钥,然后拦截到返回中间人的公钥给客户端,那么客户端就会在不知情的情况下,以为这个公钥是目标服务器的公钥,然后利用这个公钥进行数据加密(实际用的是中间人的公钥),这个时候发送加密数据后,中间人就可以利用自己的私钥对数据解密,然后利用目标服务器的公钥加密重新发送给目标服务器,这样就神不知鬼不觉的盗取到加密的明文信息了。主要问题是客户端无法知道获取到公钥是不是目标服务器的。
  3. CA证书:CA证书就是一个组织颁发的证书,CA机构通过使用自己的私钥来加密服务器的公钥,并且使用服务器的信息生成一个证书,证书签名也使用CA颁发机构的私钥进行加密。然后我们会得到一个证书文件,并且配置在我们的服务器中,nginx等对https请求会有ssl的配置参数,就是读取这一份文件。那么这个时候客户端向服务器发起请求的时候,服务器将返回这一个证书信息,这时候因为我们系统和浏览器都内置了各大CA机构的公钥信息,那么客户端只需要使用该CA证书颁发机构的公钥对证书进行解密,然后通过一些验证这个证书是否真实有效的(证书所有者,有效期等),如果有效,那么就可以解密出证书内服务器的公钥信息,然后利用这个服务器公钥进行加密信息进行传输。

回到之前所说的,为什么需要四次握手过程:

  1. 第一次握手:客户端发起https请求申请,带有支持的协议版本,如TSL1.0,一个客户端生成的随机数,支持的加密算法,支持的压缩算法。
  2. 第二次握手:服务器收到客户端的请求后,判断版本是否一致,如果不一致会关闭对话,然后服务器生成一个随机数,CA证书,确认使用的加密算法。
  3. 第三次握手:客户端收到服务器的返回后,验证证书的合法性,以及解密证书验证等,验证通过后,发送给服务器以下信息:客户端会用CA证书解密出来的服务器公钥对一个随机数进行加密,编码改变通知标识,客户端握手结束通知(包含第一次握手时所有内容的hash值,给服务器进行校验)。
  4. 第四次握手:服务器收到后,会返回编码改变通知,服务器握手结束通知(包含第二次握手时所有内容的hash值,给客户端进行校验)。

大家可以发现前3次握手中,都互相生成了一个随机码,而在第三次握手之后,客户端和服务器端都拥有了3个随机码,然而这三个随机码是给服务器和客户端用这3个随机数生成一个秘钥,最终作为对称秘钥的方式进行加密和解密的。

在SSL/TSL的四次握手后,就会继续进行http协议通信了。

我们日常使用http协议进行通信时,离不来对状态码的认识,当我们遇到接口报错的时候,状态码能很好的帮助我们定位请求失败或报错的大概原因。

  1. 1xx -> 信息性状态码(我也没有用过)
  2. 2xx -> 请求成功
    1. 200 -> 网络请求成
    2. 204 -> 请求成功,但是服务没有内容返回
    3. 206 -> 请求成功,服务器返回指定范围内的内容
  3. 3xx -> 重定向
    1. 301 -> 永久重定向(网站域名永久更改,有利于搜索引擎优化)
    2. 302 -> 临时重定向(活动页面,将首页临时重定向到活动页)
    3. 303 -> 和302一样,但是要求用户使用GET来进行请求
    4. 307 -> 和302一样
  4. 4xx -> 资源问题
    1. 400 -> 请求报文语法错误
    2. 401 -> 需要进行授权
    3. 403 -> 没有权限访问资源
    4. 404 -> 没有找到对应资源
  5. 5xx -> 服务器问题
    1. 500 -> 一般为后端发生错误,代码错误等
    2. 502 -> Bad Gateway
    3. 503 -> 服务器繁忙或者停机等情况
    4. 504 -> Bad Gateway timeout

502和504的区别,

  1. 502一般为应用无响应,可能是qps过高导致程序进程不够用,导致无法响应
  2. 504一般为网关超时,一般为客户端请求未能到达网关层导致

发表评论