前端当然要学HTTP啊,不学HTTP怎么办嘛
——一位前端工程师如是说
HTTP绝对称得上是前端的核心之一,也是我们值得花时间和精力去了解。本文将对HTTP的概念、性质和问题等进行分析,因为内容较多,又想讲的尽量简单点,会更新几天时间,同时查漏补缺。
HTTP的概念
传统概念来说,HTTP是基于TCP的一个应用层协议,是浏览器最常用的协议之一。为什么说是传统概念?从HTTP1.0~HTTP2.0,使用的都是TCP为基础的传输模式。但是到了今天,HTTP3.0已经不使用TCP而改为UDP,这部分咱们后面再细说。
既然他传统上是基于TCP的,我们先来看看TCP是个什么东西。
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
有意思了,因为HTTP是无连接,无状态的。
但是你想,要是无连接,无状态用来请求或者传输数据,那不就相当于黑天打靶——结果未知吗。所以HTTP需要基于TCP的可靠来给他自己的不可靠上一个保险。
TCP的可靠性由三次握手和四次挥手保证,细说的话,其中包括超时重传,检验和,序列号,确认号(ACK),流量控制和拥塞控制等。
HTTP报文
HTTP的报文一般分为4个部分:
1.请求(响应)行 2.请求(响应)头 3.空行 4.消息主体
请求行一般包括 GET /URL HTTP x.x (方法 URL HTTP版本 HTTP首部字段) 这样的内容,响应行一般包括 HTTP x.x 200 ok (HTTP版本 状态码 响应信息)这样的信息。
头部:
请求头包含内容一般有:
Host:请求的主机名,为虚拟主机,可以多个域名同处一个ip
User-Agent:发送请求的浏览器类型、操作系统等信息
Accept:该字段内容较多,在请求头部分为
数据格式
压缩方式:Accept-Encoding:gzip;
支持语言和字符集:Accept-Language;Accept-Charset
Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
响应头一般包括:
Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
Server:包含服务器用来处理请求的系统信息,与User-Agent请求报头相对应
其他部分为:
Date:产生消息的日期和时间
Connection:常见值有keep-alive和close
Cache-control:和Expires属于强缓存,其中Cache-control优先级>Expires,只能在服务端设置,客户端由浏览器设置,常用字段有
no-cache:不直接使用缓存,向原服务器发起请求
public:请求的发起方(浏览器)、代理缓存服务器都可以进行缓存。
private:请求的发起方(浏览器)进行缓存
no-store:不可以缓存,优先级最高
max-Age:<second>为单位,到期时间
设置了no-cache,就需要有:
Last-Modified-Since:对比上次修改时间来验证是否使用缓存,服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。
Etag:client第一次请求资源的时候,在server设置头部Etag,为hash值,字段有if-Match,if-none-Match
HTTP首部无法记录二进制值,所以要通过base64编码处理
空行
为的是隔开头部与实体,从第一个空行开始的下面内容全部设置为实体,一般采用\r\n
实体
指的就是body部分了,根据请求和相应的不同,分为请求体和响应体。
HTTP的请求方法
GET: 获取资源
HEAD: 获取资源的元信息
POST: 提交数据,即上传数据
PUT: 更新数据
DELETE: 删除数据
CONNECT: 建立连接隧道,用于代理服务器
OPTIONS: 列出可对资源实行的请求方法,用来跨域请求
TRACE: 追踪请求-响应的传输路径
其中,GET,POST,PUT经常用到。
在这里,我们着重提一提GET和POST。
GET和POST底层实现其实是差不多的,但是语义的不同,导致了分工不同。
GET和POST的差别有:
1.缓存:GET会被浏览器主动缓存;POST默认不会
2.编码:GET只能进行URL编码,只能接收ASCII字符,POST没有限制
3.参数:GET一般放在URL中,不安全;POST放在请求体中,比较安全
4.TCP:GET一次性发送请求,而POST会分为两个TCP数据包。首先发header部分,如果服务器响应,然后发body部分
HTTP状态码
状态码即HTTP的响应代码,表达的是请求或响应时的信息概括
1xx:
在与HTTP服务器沟通时使用,属于信息性状态码
2xx:
成功状态码
常见状态码有:
200:OK代表请求success
204:no content,客户端请求的资源存在,但其表示为空
206:patical content
3xx:
重定向状态码,即成功请求,但是客户端需要做一些额外的工作才能获取资源
302 found
当301,302,303状态码返回时,大多数浏览器会将post改成get
304,并不是重定向状态码,而是太久没有将网页更新,长期可能影响到网页级别
4xx:
客户端错误状态码
401 Unauthorization 请求需要有通过HTTP认证的认证信息
403 forbidden 存在但不想被你访问
404 not found 服务器上没有请求的资源
5xx:
5开头都是服务器错误状态码
500 服务器端执行请求时发生内部错误
502 Bad gateway 代理或代理与服务器之间出现问题
503 超负荷或停机
什么是HTTPS
通俗的讲,就是HTTP+加密+认证(证书)+完整性保护=HTTPS
再简单一点,就是HTTP+TLS/SSL(安全套接层) = HTTPS
并不是新的协议,而是通信接口部分用SSL和TLS协议代替,当使用SSL时,HTTP和TCP的直接通信就变成了HTTP和SSL直接通信。
SSL使用公开密钥加密:使用接收方的私有密钥来解密,解决了共享密钥加密的困难。
HTTPS使用混合加密机制:
1.Client 发送Client Hello 开始SSL通信
2.可进行SSL通信时,会以Server Hello报文作为应答
3.Server发送Certificate
4.Server Hello Done
5.Client Key Exchange
6.Client Change Cipher Spec,提示Server此后报文通信加密
7.Client Finished
8.Server Change Cipher Spec
9.Server Finished
接下来开始HTTP部分
上面提到的认证,就是客户端自报家门的过程。服务器核对的信息通常为:密码,动态令牌(一次性密码),数字证书,生物认证,IC卡
HTTP和HTTPS的区别
HTTP的端口号为80,HTTPS为443
HTTP明文传输,HTTPS加密传输,更安全的同时资源消耗也大一些
HTTPS的证书需要一定费用(不过听说最近出了个能拿到免费证书的方法)
Cookie和Session
一般情况下,我们会使用Cookie管理Session
来谈谈他们是啥吧:
Session
首先是Session,是服务端使用的一种记录客户端状态的机制,相当于服务器上的“客户明细表”
从这段话中,我们能捕捉到啥信息?服务端,记录客户端状态,翻译一下就是:
1.过多的session会给服务器很大的压力,因为每一个客户都有他独有的session。2.客户端对服务器再次访问时,只需要在session上寻找这名客户的状态即可。
Session生命周期
有关session的产生以及维护:
1.Session一般放在内存里
2.Session的内容应该尽量精简
3.在用户第一次访问服务器的时候自动创建
4.生成后继续访问会更新最后访问时间,并维护该Session
5.Session中可以禁止使用Cookie,且Session的安全性比Cookie好
然后是Cookie
Cookie可以说也是一个“通行证”,但保存在客户端。在用户第一次向服务器请求时,在response里向用户发送。是一个不到4kb的一小段文本信息,需要更新时,同样通过response发送过来一个同名的cookie进行替换更新。
理论上,一个用户的所有请求操作都应该属于同一个会话,另一用户属于另一会话。而HTTP是无状态的协议,就意味着一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。故服务器无法从连接上跟踪会话。因此,Cookie就是跟踪服务器上的会话,所以说是Cookie管理Session。
Cookie的一般参数为:
name:必需。规定 cookie 的名称。
value:必需。规定 cookie 的值。
expire:可选。客户端过期时间,Max-Age优先级更高
path:可选。cookie 的服务器路径。
domain:可选。cookie 的域名。和path一起属于Cookie的作用域
secure:可选。是否通过安全的 HTTPS 连接来传输 Cookie。
故Cookie具有不可跨域性,别国的官不能管本地的人。
大家都知道HTTP是不靠谱的,所以Cookie并不安全,可以通过设置这两个字段加强Cookie的安全性,一般也是必要的设置选项:
Secure:Cookie只在https发送,防止中间人攻击
HttpOnly:禁止JS访问Cookie,防止XSS
但Cookie仍然称不上安全,故一般不把密码等重要信息直接放在Cookie,但可以采用把账号按照一定的规则加密(如MD1,MD1算法具有不可逆性)后,连同账号一起保存(合并)到Cookie中。下次访问时只需要判断账号的加密规则是否正确即可。(*另外:中文属于Unicode字符,在内存中占4字符,而英文属于ASCII字符,占2字节。Cookie保存中文只能编码,一般为UTF-8。)
Cookie相当于Client上的通行证,由服务器response给客户端
Cookie需要浏览器的支持,浏览器可以不支持或禁用
Cookie具有不可跨域名性
Cookie的生存周期
Cookie 的有效期可以通过Expires和Max-Age两个属性来设置。
Expires:过期时间
Max-Age:一段时间间隔,单位是秒,从浏览器收到报文开始计算。
若 Cookie 过期,则这个 Cookie 会被删除,并不会发送给服务端。
小小的总结一下:
由于HTTP的无状态,为了维护连接时‘认识’的状态,就必须主动的去维护一个状态。Cookie与Session就是这样一个维护者。他们都属于会话跟踪技术,Cookie通过在Client记录信息确定用户身份,Session通过在Server端记录信息确定用户身份。
浏览器缓存策略
浏览器的缓存策略指的是浏览器发起HTTP请求和服务器沟通的过程,如果是第一次向服务器发起请求,会根据响应报文中HTTP的缓存标识,决定是否缓存结果,简单如下图:
即:
浏览器每次发起请求,都会判断是否有缓存标识和缓存结果
返回请求结果和缓存规则时,将其存入浏览器缓存,下次可以直接从浏览器缓存中取出判断
那么HTTP是否需要对浏览器缓存做更改呢?这就引出了进一步的浏览器的强制缓存和协商缓存
强制缓存
即向浏览器缓存查找请求结果,并根据该结果的缓存来决定是否使用缓存的过程。控制的字段为Expires和Cache-Control,优先级Cache-Control>Expires,其字段上面有提到。若不存在缓存结果或者结果已失效,则进入协商缓存阶段:
协商缓存
当强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存,其控制字段包括:Etag/IF-None-Match以及Last-Modified/If-Modified-Since,若协商缓存生效,则返回304状态码;若失败,则返回状态码200和请求结果。
HTTP 1.0 1.1 2.0 3.0 差别
嗯...因为这个知识点不熟糟了大盒子(真忘了),美团面试时出现了,答得不是很好,所以赶紧来写(补救)一下
HTTP1.1较于HTTP1.0主要增加了长链接,使用Connection:Keep-Alive保持TCP连接,提高网络的利用率
HTTP 2.0较于HTTP1.1 、1.0主要增加的新特性为:
多路复用——并行传输,所有通信在一个TCP连接上完成
二进制分帧——应用层和传输层之间增加一个二进制分帧层,突破HTTP1.1的性能限制,改进传输性能
头部压缩——之前的HTTP头部以纯文本发送,占据很大空间,HTTP2.0使用encoder来发送,高效的压缩算法可以有效的压缩header,减少包的数量从而降低延迟
服务器推送——服务器可以额外向客户端推送资源,主动权在服务器手上,并不需要客户端的认可
HTTP3.0主要变化
推翻HTTP基本定义的一代版本,因为HTTP将并不基于TCP进行连接,而是转而使用UDP,使用UDP如何保证传输的可靠性?原因是HTTP3.0使用了QUIC协议作为基石。
QUIC协议的特点:
0-RTT:
1)传输层0-RTT就能建立连接 2)加密层0-RTT就能进行加密连接
根文加密认证
TCP协议头没有经过任何加密和认证,在传输过程中很容易被中间网络设备篡改、注入和窃听(这也就是HTTP不靠谱的原因)。而QUIC的几乎所有报文头都是经过认证的,body都是加过密的。
向前纠错机制
少量的丢包可以通过其他包的冗余数据直接组装而无需重传