网络知识点整理-http-爱代码爱编程
请求报文格式
请求报文结构如下:
HTTP请求由请求行+请求header+空行+请求内容组成,第一行就是请求行,主要包含请求方法,URL,HTTP协议版本。第二行开始就是请求Header,请求Header后面会有一个空行,用于区分Header和请求内容。
请求行
由请求方法字段、URL字段、协议版本字段三部分构成,它们之间由空格隔开。常用的请求方法有:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。
请求头
请求头由key/value对组成,每行为一对,key和value之间通过冒号(:)分割。请求头的作用主要用于通知服务端有关于客户端的请求信息。
典型的请求头有:
User-Agent:生成请求的浏览器类型
Accept:客户端可识别的响应内容类型列表;星号* 用于按范围将类型分组。*/*表示可接受全部类型,type/*表示可接受type类型的所有子类型。
Accept-Language: 客户端可接受的自然语言
Accept-Encoding: 客户端可接受的编码压缩格式
Accept-Charset: 可接受的字符集
Host: 请求的主机名,允许多个域名绑定同一IP地址
connection:连接方式(close或keeplive)
Cookie: 存储在客户端的扩展字段
空行
最后一个请求头之后就是空行,用于告诉服务端以下内容不再是请求头的内容了。
请求内容
请求内容主要用于POST请求,与POST请求方法配套的请求头一般有Content-Type(标识请求内容的类型)和Content-Length(标识请求内容的长度)
请求响应报文
HTTP响应报文由状态行、响应头、空行和响应内容4个部分构成。第一行是状态行,由HTTP协议版本,状态码,状态描述组成,第二行开始是响应头,响应头后面是一个空行,用于区分响应头和响应内容。
由HTTP协议版本、状态码、状态码描述三部分构成,它们之间由空格隔开。
状态码由3位数字组成,第一位标识响应的类型,常用的5大类状态码如下:
1xx:表示服务器已接收了客户端的请求,客户端可以继续发送请求
2xx:表示服务器已成功接收到请求并进行处理
3xx:表示服务器要求客户端重定向
4xx:表示客户端的请求有非法内容
5xx:标识服务器未能正常处理客户端的请求而出现意外错误
常见状态码说明:
200 OK: 表示客户端请求成功
304 Not Modified:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源。
400 Bad Request: 表示客户端请求有语法错误,不能被服务器端解析
401 Unauthorized: 表示请求未经授权,该状态码必须与WWW-Authenticate报文头一起使用
404 Not Found:请求的资源不存在,例如输入了错误的url
500 Internal Server Error: 表示服务器发生了不可预期的错误,导致无法完成客户端的请求
503 Service Unavailable:表示服务器当前不能处理客户端的请求,在一段时间后服务器可能恢复正常
一般情况下,响应头会包含以下,甚至更多的信息。
Location:服务器返回给客户端,用于重定向到新的位置
Server: 包含服务器用来处理请求的软件信息及版本信息
Vary:标识不可缓存的请求头列表
Connection: 连接方式。
对于请求端来讲:close是告诉服务端,断开连接,不用等待后续的求请了。keeplive则是告诉服务端,在完成本次请求的响应后,保持连接,等待本次连接后的后续请求。
对于响应端来讲:close表示连接已经关闭。keeplive则表示连接保持中,可以继续处理后续请求。Keep-Alive表示如果请求端保持连接,则该请求头部信息表明期望服务端保持连接多长时间(秒),例如300秒,应该这样写Keep-Alive: 300
最后一个响应头之后就是空行,用于告诉请求端以下内容不再是响应头的内容了。
服务端返回给请求端的文本信息。
下面是一个实际的例子:
状态码
502是指网关(一般是Nginx)从后端服务器接受到了无效的响应结果。通常是我们的后端服务器挂了之类的。
503是请求过载,就是请求超过了Nginx限流设置的阀值,就会返回503服务不可用。
504是指网关(一般是Nginx)从后端服务器接受的响应超时了
http各版本之间的区别
HTTP1.0
无状态: 服务器不跟踪不记录请求过的状态: 可以借助 cookie/session 机制做身份认证和状态记录
无连接:
无法复用连接, 每次都需要进行三次握手, 四次挥手, 浪费网络资源
队头阻塞: HTTP1.0 规定, 在前一个响应完成后, 下一次请求才能发出, 如果前一个阻塞, 后面的请求也阻塞了
HTTP 1.1
新增 connection 字段, 设置为 keep-alive, 一次请求完成后, tcp 连接不会断开;
增加了 delete, put 等请求方式;
请求管道化, 请求可以同时发出;
增加缓存字段, cache-control;
断点续传, 允许相应数据分块传输, 利于大文件传输
管道化传输方式
请求1 --> 请求2 --> 请求3 > 响应1 --> 响应2 --> 响应3
虽然发送请求时不会阻塞, 但是响应时, 依旧是按顺序返回, 无法解决队头阻塞问题
HTTP 2.0
二进制分帧
HTTP1.x 的解析都是基于文本, HTTP 2 之后把所有的消息分成了更小的消息和帧, 采用二进制格式, 提高传输效率
多路复用
所有的请求和响应, 共享同一个 TCP 连接, 每一个连接都有一个独立的标识, 基于二进制分帧, 所有的请求乱序发送, 服务端根据标识和首部将消息重新组装起来
首部压缩
由于 HTTP 是无状态的, 每次发送请求都要携带首部字段, 造成大量的资源浪费. HTTP2 使用 encoder 来减少传输的大小, 通讯双方各自维护一份首部字典, 进行差量更新
服务端推送:服务端可以推送消息给客户端
HTTP3.0
基于google的QUIC协议,而quic协议是使用udp实现的;
减少了tcp三次握手时间,以及tls握手时间;
解决了http 2.0中前一个stream丢包导致后一个stream被阻塞的问题;
优化了重传策略,重传包和原包的编号不同,降低后续重传计算的消耗;
连接迁移,不再用tcp四元组确定一个连接,而是用一个64位随机数来确定这个连接;
更合适的流量控制。
缓存机制
从 HTTP/1.0 到 1.1、再到 2.0 版本的演进中,逐步形成了现在被称为“状态缓存”、“强制缓存”(或简称为“强缓存”)和“协商缓存”这三种 HTTP 缓存机制。
状态缓存 expires HTTP1.0
强制缓存 cache control HTTP1.1
public 可以被cdn,代理缓存
private 可以被客户端缓存
no-transform 禁止资源以任何形式被修改。比如,某些 CDN、透明代理支持自动 GZip 压缩图片或文本,以提升网络性能,而 no-transform 就禁止了这样的行为,它要求 Content-Encoding、Content-Range、Content-Type 均不允许进行任何形式的修改。
min-fresh 和 only-if-cached这两个参数是仅用于客户端的请求 Header。min-fresh 后续跟随了一个以秒为单位的数字,用于建议服务器能返回一个不少于该时间的缓存资源(即包含 max-age 且不少于 min-fresh 的数字);only-if-cached 表示服务器希望客户端不要发送请求,只使用缓存来进行响应,若缓存不能命中,就直接返回 503/Service Unavailable 错误。
must-revalidate 和 proxy-revalidatemust-revalidate 表示在资源过期后,一定要从服务器中进行获取,即超过了 max-age 的时间后,就等同于 no-cache 的行为;proxy-revalidate 用于提示代理、CDN 等设备资源过期后的缓存行为,除对象不同外,语义与 must-revalidate 完全一致。
协商缓存
根据修改时间检查
Last-Modified 是服务器的响应 Header,用来告诉客户端这个资源的最后修改时间。而对于带有这个 Header 的资源,当客户端需要再次请求时,会通过 If-Modified-Since,把之前收到的资源最后修改时间发送回服务端。
如果此时,服务端发现资源在该时间后没有被修改过,就只要返回一个 304/Not Modified 的响应即可,无需附带消息体,从而达到了节省流量的目的
唯一标识是否发生变化来进行检查”的协商缓存机制。
它的语义中也包含了两种标准参数:Etag 和 If-None-Match。Etag 是服务器的响应 Header,用于告诉客户端这个资源的唯一标识。HTTP 服务器可以根据自己的意愿,来选择如何生成这个标识,比如 Apache 服务器的 Etag 值,就默认是对文件的索引节点(INode)、大小和最后修改时间进行哈希计算后而得到的。然后,对于带有这个 Header 的资源,当客户端需要再次请求时,就会通过 If-None-Match,把之前收到的资源唯一标识发送回服务端。