从ABNF读懂HTTP协议格式

定义

HTTP(Hyper Text Transfer Protocol)超文本传输协议
HTML( Hyper Text Markup Language)超文本标记语言
URI(Uniform Resource Identifier)用于标识某一互联网资源名称的字符串(uri 包括了 url,url 用于全网做唯一标识,http://localhost:8080/html/lo... 可以称为 url/uri,但 html/login.html 只能称为 uri)

HTTP是互联网中应用最广泛的应用层协议之一,设计之初是提供一种发布和接收HTML页面的方法,由URI来标识具体的资源。

报文格式

HTTP分别规定了请求和响应的报文格式。
请求报文分为:请求行、请求头(首部行)、请求体(实体主体),GET请求没有实体主体。
响应报文分为:响应行(状态行)、响应头(首部行)、响应体(实体主体)

从ABNF读懂HTTP协议格式_第1张图片

我们从浏览器或者抓包工具中看起来会像是这样

// 请求头
GET / HTTP/1.1
Host: icp.chinaz.com

// 响应头
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8

浏览器/抓包工具 会将%20、%0D、%0A类编码展示为空格、回车、换行,但实际上数据类似于 GET%20/%20HTTP/1.1%0AHost:%20icp.chinaz.com

从ABNF读懂HTTP协议格式_第2张图片

这种报文格式是我们所最常见到的规范,但实际上有更严谨的报文格式。

ABNF

ABNF是最严谨的HTTP报文格式描述形式,来自RFC。RFC(Request For Comments 请求意见稿)是HTTP的标准,由万维网协会(W3C)、互联网工程任务组(IETF)协调制定。

ABNF报文格式将请求和响应定义在一起

HTTP-message = start-line *(header-field CRLF) CRLF [message-body]
start-line = request-line / status-line

ABNF定义的HTTP报文格式为:一个开始行(请求行或者响应行),0个或者多个首部行和回车换行的整体,一个回车换行,0个或者1个实体

标识 含义
* 0个或多个。2 表示至少2个,3 6 表示3到6个
/ 任选一个
() 表示为一个整体
[] 可选项,可有可无

对于 request-linestatus-lineheader-fieldmessage-body 也有更详细的定义。

request-line
request-line = method SP request-target SP HTTP-version CRLF
HTTP-version = HTTP-name "/" DIGIT "." DIGIT
HTTP-name = %x48.54.54.50;HTTP

request-line 组成格式为:请求方法、空格、请求目标、空格、请求的HTTP版本、回车换行。转换成具体的数据格式可能是这样: GET /index.html HTTP/1.1

标识 含义
SP space 空格
DIGIT 数字
%x48.54.54.50 表示四个字节,分别为%x48 %x54 %x54 %x50,为字符 HTTP
;HTTP 分号后面都是注释内容
status-line
status-line = HTTP-version SP status-code SP reason-phrase CRLF
status-code = 3DIGIT
reason-phrase = *( HTAB / SP / VCHAR / obs-text )

status-line 组成格式:HTTP版本、空格、状态码、空格、响应描述、回车换行,最终数据格式可能为:HTTP/1.1 200 OK

标识 含义
HTAB tab键
VCHAR 字符串如 OK
header-field
header-field = field-name ":" OWS field-value OWS
field-name = token
field-value = *(field - content / obs-fold)
OWS = *(SP | HTAB)

header-field 由名称和值这样的键值对组成,中间以空格或者TAB相隔,最终的数据格式类似于:Connection: keep-alive

message-body
message-body = *OCTET

message-body 不一定有,比如 GET 请求头就没有,当存在的时候,可以为任意内容,比如请求 html 文件,响应为 html 代码。

标识 含义
OCTET 8位数据,一个字节,任意内容

追踪HTTP报文

说完了HTTP报文的格式,那么我们该怎么获取HTTP报文呢?使用 nodejs 起了一个服务,端口号是8000,有三种不同的获取HTTP报文的方式。

浏览器

在浏览器中获取报文非常的方便,找到对应的请求,点击 Response Headers 的【View Source】就可以看到 HTTP 的响应头信息

从ABNF读懂HTTP协议格式_第3张图片

但响应体没有包括在这里,需要点击 Response 才能看到

从ABNF读懂HTTP协议格式_第4张图片

抓包工具

通过抓包工具 wireshark 获取到的协议内容更为完整,多个请求都会出现在追踪的HTTP流数据里。

从ABNF读懂HTTP协议格式_第5张图片

根据ABNF定义,message-body 后没有【回车换行】字符,响应体后紧接着下一个请求的报文。

从ABNF读懂HTTP协议格式_第6张图片

Xshell

安全终端模拟软件Xshell,可以直接面向HTTP报文与服务器交互,更清晰、直观地看到请求报文、响应报文的内容。

通过 telnent 建立连接,输入请求头

GET / HTTP/1.1 HOST: localhost: 8000

从ABNF读懂HTTP协议格式_第7张图片

它还具备以上两种方式所没有的功能,就是检验请求报文格式的正确与否,当请求行与请求头之间没有回车换行时,会报错400

从ABNF读懂HTTP协议格式_第8张图片

总结

  • HTTP 超文本传输协议,在应用层,可以用来获取HTML页面、图片、字体等资源
  • ABNF规定了HTTP最严谨的报文格式
  • 浏览器、抓包工具、终端模拟工具都可以获取到HTTP的请求报文

以上就是 从ABNF读懂HTTP协议格式的内容 , 更多有关 前端网络协议 的内容可以参考我其它的博文,持续更新中~

你可能感兴趣的:(网络http)