一、HTTP简介
1.1 HTTP是什么?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
HTTP三点注意事项:
HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
HTTP是无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它 必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
1.2 HTTP报文格式
1.2.1 HTTP 常见请求头
Accept:览器支持的MIME 媒体类型, 比如: text/html, application/json, image/webp等
Accept-Encoding: 浏览器发给服务器,声明浏览器支持的编码类型,gzip, deflate
Accept-Language: 客户端接受的语言格式,比如 zh-CN
Connection:keep-alive , 开启HTTP持久连接
Host:服务器的域名
Origin:告诉服务器请求从哪里发起的,仅包括协议和域名CORS跨域请求中可以看到response有对应的header,Access-Control-Allow- Origin
Referer:告诉服务器请求的原始资源的URI,其用于所有类型的请求,并且包括:协议+域名+查询参数; 很多抢购服务会用这个做限制,必须通过某个入来进来才有效
User-Agent: 服务器通过这个请求头判断用户的软件的应用类型、操作系统、软件开发商以及版本号、浏览器内核信息等;风控系统、反作弊系统、反爬虫系统等基本会采集这类信息做参考
Cookie: 表示服务端给客户端传的http请求状态,也是多个key=value形式组合,比如登录后的令牌等
Content-Type:HTTP请求提交的内容类型,一般只有post提交时才需要设置,比如文件上传,表单提交等
1.2.2 HTTP 常见响应头
Allow:服务器支持哪些请求方法
Content-Length:响应体的字节长度
Content-Type: 响应体的MIME类型
Content-Encoding:设置数据使用的编码类型
Date: 设置消息发送的日期和时间
Expires:设置响应体的过期时间,一个GMT时间,表示该缓存的有效时间
cache-control:Expires的作用一致,都是指明当前资源的有效期, 控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据,优先级高于Expires,控制粒度更细,如max-age=240,即4分钟
Location:表示客户应当到哪里去获取资源,一般同时设置状态代码为3xx
Server:服务器名称
Transfer-Encoding:chunked 表示输出的内容长度不能确定,静态网页一般没,基本出现在动态网页里面
Access-Control-Allow-Origin:定哪些站点可以参与跨站资源共享
1.2.3 HTTP content-type
Content-Type(内容类型),一般是指网页中存在的 Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。Content-Type标头告诉客户端实际返回的内容的内容类型。
语法格式:
1.2.4 常见MIME 类型
MIME (Multipurpose Internet Mail Extensions)是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL,因此 We b服务器在响应头中添加正确的 MIME 类型非常重要。如果配置不正确,浏览器可能会无法解析文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。
二、HTTP1.0、HTTP1.1、HTTP2.0和HTTP3.0的特点及其区别
2.1 HTTP 1.0
1、无状态,无连接
3、短连接:每次发送请求都要重新建立tcp请求,即三次握手,非常浪费性能
3、无host头域,也就是http请求头里的host,
4、不允许断点续传,而且不能只传输对象的一部分,要求传输整个对象
2.2 HTTP 1.1
1、长连接,流水线,使用connection:keep-alive使用长连接
2、请求管道化
3、增加缓存处理(新的字段如cache-control)
4、增加Host字段,支持断点传输等
5、由于长连接会给服务器造成压力
2.3 HTTP 2.0
1、二进制分帧
2、头部压缩,双方各自维护一个header的索引表,使得不需要直接发送值,通过发送key缩减头部大小
3、多路复用(或连接共享),使用多个stream,每个stream又分帧传输,使得一个tcp连接能够处理多个http请求
4、服务器推送(Sever push)
2.4 HTTP 3.0
1、基于google的QUIC协议,而quic协议是使用udp实现的
2、减少了tcp三次握手时间,以及tls握手时间
3、解决了http 2.0中前一个stream丢包导致后一个stream被阻塞的问题
4、优化了重传策略,重传包和原包的编号不同,降低后续重传计算的消耗
5、连接迁移,不再用tcp四元组确定一个连接,而是用一个64位随机数来确定这个连接
6、更合适的流量控制
2.5 TCP 与 QUIC
2.5.1 TCP
1、不支持流级复用,TCP会将所有对象序列化在同一个流中,因此,它不知道TCP段的对象级分区,无法在同一个流中复用数据包
2、会产生冗余通信,tco三次连接握手会有冗余的消息交换序列
3、可能会间歇性地挂起数据传输,tcp中有个因为序列顺序处理丢失的问题的缺陷称为行头阻塞
2.5.2 QUIC
1、同样拥有头部压缩,并优化了对乱序发送的支持,也优化了压缩率
2、放弃tcp,通过udp建立,提高了连接建立的速度,降低了延迟
3、tcp本身是无法解决队头拥塞,quic则解决了这个问题
4、Connection ID使得http3支持连接迁移以及NAT的重绑定
三、HTTPS
HTTP1.x在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性,为了传输过程的数据安全行问题,网景在1994年创建了HTTPS,并应用在网景导航者浏览器中。最初,HTTPS是与SSL一起使用的,在SSL逐渐演变到TLS时(其实两个是一个东西,只是名字不同而已),最新的HTTPS也由在2000年五月公布的RFC 2818正式确定下来。简单来说,HTTPS就是安全版的HTTP,并且由于当今时代对安全性要求更高
3.1 HTTPS 请求流程
1、客户端发起 HTTPS 请求
这个没什么好说的,就是用户在浏览器里输入一个https 网址,然后连接到 server 的 443 端口。
2、服务端的配置
采用HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl 就是个不错的选择,有 1 年的免费服务)。
这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
3、传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。
4、客户端解析证书
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。
如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。
5、传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
6、服务端解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7、传输加密后的信息
这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。
8、客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。
3.2HTTPS与HTTP的一些区别
HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的TLS加密传输协议。
HTTP和HTTPS使用的是完全不同的连接方式,用的默认端口也不一样,前者是80,后者是443。
HTTPS的连接很简单,HTTPS协议是由TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
四、HTTP请求方法
根据HTTP标准,HTTP 请求可以使用多种请求方法。
HTTP1.0定义了三种请求方法: GET, POST 和 HEAD 方法。
HTTP1.1新增了六种请求方法: OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
4.1 HTTP 请求方法
4.2 安全性和幂等性
4.2.1安全性
安全是指方法不会“破坏”服务器上的资源,即不会对服务器资源造成实质的修改,安全方法是那些可以被缓存、对资源无损预加载的方法。
安全:GET、HEAD、OPTIONS、TRACE、CONNECT
不安全:POST、PUT、DELETE、PATCH
1、GET 和 HEAD 方法是“安全”的,因为它们是“只读”操作;
2、POST/PUT/DELETE 操作会修改服务器上的资源,增加或删除数据,所以是“不安全”的。
4.2.2 幂等性
幂等意思是多次执行相同的操作,结果也都是相同的,即多次“幂”后结果“相等”。
注意:这里的幂等性不是指只要使用了相应的方法,就能保证我们的接口是幂等的。这里描述的是一种规范,让 使用我们接口的人知道只要看到我们接口,就能我们的接口会对我们的资源或数据产生怎样的影响,就能选择合适的方法实现相关的功能。
幂等:GET、HEAD、DELETE、PUT、OPTIONS、TRACE、CONNECT
非幂等:POST、PATCH
GET和 HEAD 既是安全的也是幂等的,DELETE 可以多次删除同一个资源,效果都是“资源不存在”,所以也是幂等的。
PUT是“替换或更新数据”,多次更新一个资源,资源还是会第一次更新的状态,所以是幂等的。
POST是“新增或提交数据”,多次提交数据会创建多个资源,所以不是幂等的。
注意:HTTP PUT方法和HTTP PATCH方法,都是用来表述更新资源,它们之间有什么区别呢?
我们一般的理解是PUT表示更新全部资源,PATCH表示更新部分资源。首先,这个是我们遵守的第一准则。PATCH方法是非幂等的,因此我们在设计我们服务端的API的时候,也需要考虑。如果,我们想要明确的告诉调用者我们的资源是幂等的,我的设计更倾向于使用HTTP PUT方法。
五、HTTP的简单请求与复杂请求
5.1 概述
在讲HTTP简单与复杂请求之前先了解几个概念:同源政策,跨域,跨域预检;
5.1.1 同源政策
5.1.2 跨域与跨域预检
跨域:不满足同源政策,即发起http 请求的地址(源地址)与请求的地址(目标地址)在“协议、域名(ip)、端口”三个同源条件中有“其中一个不符合”的都是“跨域”的http请求。
跨域预检:跨域共享标准规范要求,对那些可能对服务器数据产生副作用的HTTP请求方法,浏览器必须首先使用 OPTIONS 方法发起一个预检请求,从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的HTTP请求。
在前端中我们一般不会主动发起这个请求,但是往往你可以看到浏览器中相同的请求发起了2次。其实,这是因为在跨域的情况下,在浏览器发起"复杂请求"时主动发起的。;某些请求不会触发CORS(跨域)预检请求,这样的请求一般称为"简单请求",而会触发预检的请求则称为"复杂请求"。
5.2 HTTP的简单请求
5.3 HTTP的复杂请求
不符合以上条件的请求就肯定是复杂请求了。复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为 预检请求,该请求是 option 方法的,通过该请求来知道服务端是否允许跨域请求。
5.3.1 Options关键的请求头字段
5.3.2 Options请求优化
当我们发起跨域请求时,如果是简单请求,那么我们只会发出一次请求,但是如果是复杂请求则先发出options请求,用于确认目标资源是否支持跨域,然后浏览器会根据服务端响应的 header 自动处理剩余的请求,如果响应支持跨域,则继续发出正常请求,如果不支持,则在控制台显示错误。由此可见,当触发预检时,跨域请求便会发送 2 次请求,既增加了请求数,也延迟了请求真正发起的时间,严重影响性能。所以,我们可以对 Options请求进行优化。优化方法如下:
1、转为简单请求,如用JSONP做跨域请求
2、对options请求进行缓存,服务器端设置 Access-Control-Max-Age 字段,那么当第一次请求该 URL 时会发出 OPTIONS 请求,浏览器会根据返回的 Access-Control-Max-Age 字段缓存该请求的 OPTIONS 预检请求的响应结果(具体缓存时间还取决于浏览器的支持的默认最大值,取两者最小值,一般为 10 分钟)。在缓存有效期内,该资源的请求(URL 和 header 字段都相同的情况下)不会再触发预检。(chrome 打开控制台可以看到,当服务器响应 Access-Control-Max-Age 时只有第一次请求会有预检,后面不会了。注意要开启缓存,去掉 disable cache 勾选。)
六、HTTP状态代码
1XX — — 信息,服务器收到请求,需要请求者继续执行操作
2XX — — 成功,操作被成功接收并处理
3XX — — 重定向,需要进一步的操作以完成请求
4XX — — 客户端错误,请求包含语法错误或者无法完成请求
5XX — — 服务器错误,服务器在处理请求的过程中发生了错误
1、“xx”表示 00 到 99 之间的不同数字
2、以数字“2”开头的状态代码表示成功。例如,在客户端请求网页后,最常见的响应状态码为“200 OK”,这表示请求已正确完成。
3、如果响应以“4”或“5”开头,则表示存在错误,并且不会显示网页。
以“4”开头的状态代码表示客户端错误(在 URL 中打错字时,经常会遇到“404 NOT FOUND”状态代码)。
以“5”开头的状态代码表示服务器端出了问题。
4、状态码也可以以“1”或“3”开头,分别表示信息响应和重定向。
6.1 状态代码1XX — — 信息
6.2状态代码2XX — — 成功
6.3状态代码3XX — — 重定向
6.4状态代码4XX — — 客户端错误
6.5状态代码5XX — — 服务端错误