HTTP是超文本传输协议,也就是HyperText Transfer Protocol。HTTP的名字「超文本传输协议」,它可以拆成三个部分:
五大类HTTP状态码
大类 | 具体含义 | 常见的状态码 |
---|---|---|
1×× | 提示信息,表示目前协议处理的中间状态,还需要后续的操作 | |
2×× | 成功,报文已经收到并被正确处理 | 200、204、206 |
3×× | 重定向,资源位置发生变动,需要客户端重新发送请求; | 301、302、304 |
4×× | 客户端错误,请求报文有误,服务器无法处理 | 400、403、404 |
5×× | 服务器错误,服务器在处理请求时内部发生了错误 |
1××
1××类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
2××
2××类状态码表示服务器成功处理了客户端的请求,也就是我们最愿意看到的状态。
「200 OK」是最常见的成功状态码,表示一切正常。如果是非HEAD请求,服务器返回的响应头都会有body数据。
「204 No Content」也是常见的成功状态码,与200OK基本相同,但是响应头没有body数据。
「206 Partial Content」是应用于HTTP分块下载或断电续传,表示响应返回的body数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
3××
3××类状态状态码表示客户端请求的资源发生了变动,需要客户端用新的URL重新发送请求获取资源,也就是重定向。
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的URL再次访问。
「302 Moved Temporarily」表示临时重定向,说明请求的资源还在,但暂时需要用另一个URL来访问。
301和302都会在响应头里面使用字段Location,指明后续需要跳转的URL,浏览器会自动重定向新的URL.
「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,用于缓存控制。
4××
4××类状态码表示客户端发送的报文有误,服务器无法处理。
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求错误。
「404 Not Found」表示请求的资源在服务器器上不存在或未找到,所以无法提供给客户端。
5××
5××类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
「500 Internal Server Error」与400类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
「503 Service Unavailabe」表示服务器当前很忙,暂时无法响应服务器,类似“网络服务很忙,请稍后重试”的意思。
客户端发送请求时,用来指定服务器的域名。
比如:Host:A.com
服务器在返回数据时,会有Content-Length字段,表明本次回应的数据长度。
比如:Content-Length: 1000
表示本次服务器返回的数据长度是1000个字段。
Connection字段最常用语客户端要求服务器使用TCP持久化连接,以便其他请求复用。
HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的HTTP,需要指定Connection首部字段的值为Keep-Alive.
比如:Connection:keep-alive
一个可以复用的TCP连接就建立了,直到客户端或服务器主动关闭连接。
Content-Type字段主要用于服务器回应时,告诉客户端,本次数据是什么格式。
比如:Content-Type:text/html;charset=utf-8
上面的类型表明,发送的是网页,而且编码是UTF-8。客户端请求的时候,可以使用Accept字段声明自己可以接受哪些数据格式。
Accept: /
上面代码中,客户端声明自己可以接受任何格式的数据。
Content-Encoding字段说明数据的压缩方法。表示服务器返回的数据使用什么压缩格式。
比如:Content-Encoding:gzip
上面表示服务器返回的数据采用gzip方式压缩,告知客户端需要用此方式解压。
客户端在请求时,用Accept-Encoding字段说明自己可以接受哪些压缩方法。
Accept-Encoding:gzip,deflate
GET方法的含义是请求从服务器获取资源,这个资源可以是静态的文本、页面、图片视频等。
POST方法则是相反操作,它向URI指定的资源提交数据,数据就放在报文的body里。
安全和幂等的概念:
GET 方法是安全且幂等的
POST方法是不安全的也不是幂等的
1996/5
HTTP/1.0
1997/1
HTTP/1.1
1.1 版本最大变化,就是引入了持久连接(persistent conncetion),即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive
客户端和服务器发现对方一段时间没有活动,就可以主动关闭连接。不过,规范的做法是,客户端在最后一个请求时,发送Connection: close
,明确要求服务器关闭连接。
Connection: close
目前,对于同一个域名,大多数浏览器允许同时建立6个持久连接。
举例:
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Machintosh; Intel Mac OS X 10_10_5)
Accept: */*
说明:第一行是请求命令,必须是在尾部添加协议版本(HTTPP/1.0)。后面是多行头信息,描述客户端的情况。
服务器的响应格式:
HTTP/1.O 200 OK
Content-Type: text/plain
Content-Length: 13784
Expires: Thu, 05 DEC 1997 15:55:28 GMT
Server: Apache 0.8.4
Hello Word
说明:第一行是“协议版本 + 状态码(status code) + 状态描述”
HTTP 是「无状态、明文传输」
早期HTTP/1.0 性能上的一个很大问题,那就是每发起一个请求,都要建立一次TCP连接(三次握手),而且是串行请求,做了无畏的TCP连接建立和断开,增加了通信开销。
为了解决上述TCP连接问题,HTTP/1.1提出了长连接的通信方式,也叫持久连接。这种方式的好处在于减少了TCP连接的重复建立和断开造成的额外开销,减轻了服务器的负载。
持久连接的特点是,只要任意一端没有明确剔除断开连接,则保持TCP连接状态。
HTTP/1.1 版本引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。问题,要是前面的回应特别慢,后面就会有许多请求排毒等着。这称为「队头阻塞」。(注意:现代浏览器默认是不开启 HTTP Pipelining )
「队头阻塞」的模式加剧了HTTP的性能问题。总之HTTP/1.1 的性能一般般,后续的HTTP/2 和HTTP/3 就是在优化HTTP的性能。
容易混淆的概念
TCP的keep alive和HTTP的Keep-alive是不同层次的概念:
TCP keep alive的表现:
当一个连接“一段时间”没有通讯数据时,一方会发出一个心跳包(Keep Alive包),如果对方有回应,则表明当前连接有效,继续监控。这个“一段时间”可以设置,具体做法google。如下:
HTTPS建立一个连接,要花费6次交互,先是建立三次握手,然后是TLS/1.3 的三次握手。QUIC直接把以往的TCP和TLS/1.3 的6次交互合并成3次,减少了交互次数。QUIC是在UDP之上的伪TCP+TLS+HTTP/2的多路复用协议。
HTTP/1.1相比HTTP/1.0性能上的改进:
HTTP/1.1 自身的性能瓶颈:
HTTP/2协议是基于HTTPS的,所以HTTP/2的安全性是有保障的。
HTTP/2相比HTTP/1.1性能上的改进:
HTTP/2会压缩头(Header),如果你同时发送多个请求,他们的头是一样的或者是相似的,那么协议会帮你消除重复的部分。
HTTP/2不再像HTTP/1.1里的纯文本的报文,而是全面采用了二进制格式。头信息和数据体都是二进制,并且统称为帧(frame):头信息帧和数据帧。
HTTP/2的数据包不是按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。客户端还可以指定数据流的优先级。
HTTP/2的连接可以并发多个请求(多路复用),而不用按照顺序一一对应。移除了HTTP/1.1中的串行请求,不需要排队等待,不会再出现「队头阻塞」问题。
比如:在一个TCP连接里,服务器收到了客户端A和B的两个请求,如果发现A处理过程非常耗时,于是就回应A请求已经处理好的部分,接着回应B请求,完成后,再回应A请求剩下的部分。
服务器推送,HTTP/2在一定程度上改善了传统的「请求-应答」工作模式,服务不再是被动地响应,也可以主动向客户端发送消息。
比如:在浏览器刚请求HTML的时候,就提前把可能用到的JS、CSS文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送(Server Push,也叫Cache Push)
HTTP/2有哪些缺陷?HTTP/3做了哪些优化?