美文网首页
HTTP之三:HTTP报文详解

HTTP之三:HTTP报文详解

作者: longLiveData | 来源:发表于2020-05-25 10:19 被阅读0次

本文仅供笔者平日学习笔记之用,侵删
原文:https://mp.weixin.qq.com/s/wZONAYSlkufds0LMzoE-9g

报文包括:

  • 请求报文
  • URI
  • 响应报文
  • 请求体
  • Cookie
  • HTTP代理

客户端与服务端进行交互的信息为报文。客户端为请求报文,服务端为响应报文。我们先用Wireshark抓一个博客看看。

Wireshark(前称Ethereal)是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换。

GET /article/12 HTTP/1.1
Host: www.xxx.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: SESSION=so9nlsvenminor5abs65sh9dsa

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 17 May 2020 17:04:29 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: blade-2.0.6-BETA
Content-Encoding: gzip

1、请求报文

请求报文通常由三部分组成:

  • 起始行:描述请求或者响应的基本信息
  • 头部字段集合:key-value形式说明报文
  • 消息正文:实际传输诸如图片等信息。具体如下图试试

请求方法:一共有八种方法选择,如下图所示。采用不同的方法获取不同的资源:

其中非常常见的几种请求方法:

  • GET:从服务器中取资源。可以请求图片,视频等
  • HEAD:和GET类似,但是从服务器请求的资源不会返回请求的实体数据,只会返回响应头
  • POST/PUT:对应于GET,向服务器发送数据

2、URI

统一资源标识符(Uniform Resource Identifier),严格来说不等于网址,它包含URL和URN,可是URL太出名了以致于URL="网址"。无论开发,测试运维配置都离不开URI。

网络层的IP主要目的是解决路由和寻址。现在的IP地址按照"."分割,总共2的32次方大约42亿。对于计算机来说比较方便,但是对于人类来说还是不容易记忆,此时出现DNS了,他把IP地址映射为我们平时常见的"redis.org",按照"."分割域名,从左到右级别越高,最右边为"顶级域名"。如下图所示:

好了,现在TCP提供可靠(数据不丢失)且字节流(数据完整性),而且也有方便我们记忆的域名,但是互联网资源千万种,也不知道访问什么(图片,文字,视频一大堆),这个时候URI(统一资源标识符)出现了,那长啥样?

image
  • 协议名:HTTP协议,另外还有ftp等协议。告知访问资源时使用什么协议。

  • 紧接着是分隔符:"://"

  • 主机名:标记互联网主机,可以是IP也可以是域名,如果不写端口则使用默认端口,例如HTTP为80,HTTPS为443。

  • 登录认证信息:登录主机时的用户名密码(不建议,直接告诉了别人你的隐私信息)

  • 主机名:此处可以是域名也可以是IP,如果不写端口号则是默认端口。比如HTTP默认端口为80,HTTPS默认端口为443。

  • 资源所在位置:资源在主机上的位置,使用“/”分隔多级目录,在这里是“/en/download.html”。注意,必须"/"开头。

  • 参数:用"?"开始,表示额外的请求要求。通常使用"key=value"的方式存在,如果多个"key=value"则使用"&"相连。**

看几个例子:
http://nginx.org/en/download.html
file:///E:/Demo/index/

这里注意是三个"///",因为前面"://"作为分隔符,资源路径按照"/"开头。

既然规则这么多,对于接收方而言需要完成的解析也需要遵守规则,全球用户很多使用HTTP,每个国家地区所使用语言不同,HTTP为了能对其进行统一处理,引入了URI编码,方法比较简单,将非ASCII或者特殊字符全部转换为十六进制字节值,同时在前面加入"%"。比如空格被转换为"%20","中国"就编码为"%E4%B8%AD%E5%9B%BD%0A"。

3、响应报文

状态行----服务器响应的状态。

<1>版本号:使用的HTTP什么版本

<2>状态码:不同数字代表不同的结果,就如我们在编码时,通过返回不同的值代表不同的语义。

**状态码一共分为5类。

  • 1××:处于中间状态,还需后续操作

  • 2××:成功收到报文并正确处理

"200OK"
最常见的成功状态码,表示一切正常,客户端获得期许的处理结果。如果不是Head请求,那么在响应头中通常会有Body数据。
"204No Content"
这个的含义和"200"很相似,不同之处在于它的响应头中没有Body数据
"206Partial Content"
是 HTTP 分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 一样,也是服务器成功处理了请求,但Body 里的数据不是资源的全部,而是其中的一部分。状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 Body 数据的具体范围,供客户端确认,例如“Content-Range: bytes 0-99/5000”,意思是此次获取的是总计5000 个字节的前 100 个字节。

  • 3××:重定向到其他资源位置

"301Moved Permanently"
“永久重定向”,意思是本地请求的资源以及不存在,使用新的URI再次访问。
“302Found”
“MovedTemporarily”,“临时重定向”,临时则所请求的资源暂时还在,但是目前需要用另一个URI访问。
301和 302 通过在字段Location中表明需要跳转的URI。两者最大的不同在于一个是临时改变,一个是永久改变。举个例子,有时候需要将网站全部升级为HTTPS,这种永久性改变就需要配置永久的"301"。有时候晚上更新系统,系统暂时不可用,可以配置"302"临时访问,此时不会做缓存优化,第二天还会访问原来的地址。
“304Not Modified”
运用于缓存控制。它用于 If-Modified-Since 等条件请求,表示资源未修改,可以理解成“重定向已到缓存的文件”(即“缓存重定向”)。

  • 4××:请求报文有误,服务器无法处理

"400Bad Request"
通用错误码,表示请求报文有错误,但是这个错误过于笼统。不知道是客户端还是哪里的错误,所以在实际应用中,通常会返回含有明确含义的状态码。
“403Forbidden”:
注意了,这一个是表示服务器禁止访问资源。原因比如涉及到敏感词汇、法律禁止等。当然,如果能让客户端有一个清晰的认识,可以考虑说明拒绝的原因并返回即可。
“404Not Found”
这可能是我们都知道且都不想看到的状态码之一,它的本意是想要的资源在本地未找到从而无法提供给服务端,但是现在,只要服务器"耍脾气"就会给你返回 404,而我们也无从得知后面到底是真的未找到,还是有什么别的原因
"405Method Not Allowed"
获取资源的方法好几种,我们可以对某些方法进行限制。例如不允许 POST 只能 GET
"406Not Acceptable"
客户端资源无法满足客户端请求的条件,例如请求需要中文但只有英文
"408Request Timeout"
请求超时,服务器等待了过长的时间
"409Conflict"
多个请求发生了冲突,可以理解为多线程并发时的竞态
413Request Entity Too Large
请求报文里的 body 太大
414Request-URI Too Long
请求行里的 URI 太大
429Too Many Requests
客户端发送了太多的请求,通常是由于服务器的限连策略
431Request Header Fields Too Large
请求头某个字段或总体太大;

  • 5××:服务器错误,服务器对请求出的时候发生内部错误。

“500Internal Server Error”
和400类似,属于一个通用的错误码,但是服务器到底是什么错误我们不得而知。其实这是好事,尽量少的将服务器资源暴露外网,尽量保证服务器的安全。
“502Bad Gateway”
通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。
“503Service Unavailable”
表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。
503是一个“临时”的状态:暂时比较忙,稍后提供服务。在响应报文中的“Retry-After”字段,指示客户端可以在多久以后再次尝试发送请求。

4、请求体

上面大部分都是涉及到Header部分,还有非常重要的Body,Everybody。

头字段注意事项:

<1> 字段名不区分大小写,例如“Host”也可以写成“host”,但首字母大写的可读性更好;
<2> 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线"_"。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正确的字段名;
<3> 字段名后面必须紧接着“:”,不能有空格,而":"后的字段值前可以有多个空格;
<4> 字段的顺序是没有意义的,可以任意排列不影响语义;
<5> 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。

HTTP的body常常被分为这几种的类别:

<1> text:超文本text/html,纯文本text/plain
<2> audio/video:音视频数据
<3> application: 可能是文本,也可能是二进制,交给上层应用处理
<4> image: 图像文件。image/png等

但是带宽一定,数据大了通常考虑使用压缩算法进行压缩,在HTTP中使用Encoding type表示,常用的压缩方式有下面几种:

<1> gzip:
一种数据格式,默认且目前仅使用deflate算法压缩data部分。
<2>deflate:
deflate是一种压缩算法,是huffman编码的一种加强。
<3>br:
br通过变种的LZ77算法、Huffman编码以及二阶文本建模等方式进行数据压缩,其他压缩算法相比,它有着更高的压塑压缩效率。

使用相应的压缩方法在带宽一定的情况下确实有不错的效果,但是GZIP等主要针对文件压缩效果不错,但是对视频就不行了。这个时候是不是可以使用数据结构中常用的分而治之,大化小再合并的方式呢。

OK,在报文中使用"Transer-Encoding:chunked"表示,代表Body部分数据是分块传输的。另外在Cody中存在一个Content-length字段表示Body的长度,两者不能共存,另外很多时候是流式数据,Body中没有指明Content-length,这个时候一般就是Chunked传输了。

现在可以通过采用分块的方式增强带宽的利用率,那他的编码规则如何呢?

<1> 每一个分块包含长度和数据块
<2> 长度头按照CRLF结束
<3> 数据块在长度快后,且最后CRLF结尾<4>使用长度0表示结束,"0\r\n\r\n"

我们还是看图加深印象:

分块解决了咋们一部分问题,但是有的时候我们想截断发送怎么办呢。在HTTP中提供了使用字段“Accept - Ranges: bytes”,明确告知客户端:“我是支持范围请求的”。那么Range范围是怎样的呢,Range从0开始计算,比如Range:0-5则读取前6个字节,服务器收到了这个请求,将如何回应呢

<1> 合法性检查。比如一共只有20字节,但是请求range:100-200。此时会返回416----"范围请求有误"
<2> 范围正常,则返回216,表示请求数据知识一部分
<3> 服务器端在相应投资端增加Content-Range,格式"bytes x-y/length"。

敲黑板:断点续传怎么操作?

<1> 查看服务器是否支持范围请求并记录文件大小
<2> 多个线程分别负责不同的range
<3> 下载同时记录进度,即使因为网络等原因中断也没事,Range请求剩余即可。

现在我们通过MIME-TYPEEncoding-type可以知道body部分的类型,下一步将是对内容进行协商。HTTP中,请求体中使用Accept告诉服务端需要什么类型数据(我能处理哪些类型数据),响应头中使用Content表明发送了什么类型数据,具体如下图所示:

好了,为了各个国家民族顺利友好的沟通和明确的区分。HTTP请求头中使用"type-subtype",注意此时分隔符是"-"。比如EN-GB表示英式英语,ZH-CN表示常用的汉语,那对于客户端而言,它通过Accept-Language来标记自己可以理解的自然语言,对应的服务端使用Content-Language表明实体数据使用的语言类型,如下图所示。

5、Cookie机制

HTTP是无状态、无记忆的,Cookie机制的出现让其有记忆功能,是怎么实现呢?

从上图我们可以知道Cookie是由浏览器负责存储,并不是操作系统负责,我们换个浏览器。打开同样的网页,服务就认不出来了。

Cookie常见的应用一个是身份识别,一个是广告追踪,比如我们在访问网页视频或者图片的时候,广告商会悄悄给我们Cookie打上标记,方便做关联分析和行为分析,从而给我推荐一些相关内容。

6、HTTP代理

之前介绍的都是一问一答的情景,但是在大部分的情况下都会存在多台服务器进行通信服务。其中比较常见的就是在请求方与应答方中间增加一个中间代理。

代理作为中间位置,相对请求方为服务端,相当于后端服务端为请求方。代理常见的功能为负载均衡。在负载均衡中需要区分正向代理与反向代理,其中也就会涉及调度算法,比如轮询,一致性哈希等。

代理作为隐藏身份,相当于隐藏了真实的客户端与服务端。

相关文章

  • HTTP之三:HTTP报文详解

    本文仅供笔者平日学习笔记之用,侵删原文:https://mp.weixin.qq.com/s/wZONAYSlku...

  • http报文详解

    HTTP工作原理 一、报文的组成 HTTP报文大致分为报文首部和报文主体两块,中间用空行来划分。通常,不一定有报文...

  • http报文详解

    http的报文 分为两个报文:请求报文和响应报文一、请求报文分为四部分:请求行、请求头部、空行和请求数据1、请求行...

  • HTTP报文详解

    一、HTTP协议 1.简介 HTTP协议(Hyper Text Transfer Protocol,超文本传输协议...

  • 详解http报文

    摘要 作为一个web开发者,每天都在使用者Http协议,却总是一知半解。本文参看Http RFC7230规范,梳理...

  • 详解http报文(2)-web容器是如何解析http报文的

    摘要 在详解http报文一文中,详细介绍了http报文的文本结构。那么作为服务端,web容器是如何解析http报文...

  • HTTP/1.1报文详解

    本文为《三万长文50+趣图带你领悟web编程的内功心法[https://www.itzhai.com/articl...

  • HTTP协议和socket连接

    HTTP的格式 HTTP请求、响应报文格式 HTTP请求行、请求头、请求体详解 TCP连接、HTTP连接与Sock...

  • HTTP协议报文及Chrome Network常用功能

    HTTP协议报文 Http协议报文分为【Http请求报文】和【Http响应报文】 HTTP请求报文 Http请求报...

  • HTTP协议基础# Chapter3 HTTP报文

    Chapter3 HTTP报文 1 HTTP 报文 HTTP报文:::用于HTTP协议交互的信息HTTP报文= 报...

网友评论

      本文标题:HTTP之三:HTTP报文详解

      本文链接:https://www.haomeiwen.com/subject/ivueahtx.html