从ABNF读懂HTTP协议格式
定义
HTTP(Hyper Text Transfer Protocol)超文本传输协议
HTML( Hyper Text Markup Language)超文本标记语言
URI(Uniform Resource Identifier)用于标识某一互联网资源名称的字符串(uri 包括了 url,url 用于全网做唯一标识,http://localhost:8080/html/login.html 可以称为 url/uri,但 html/login.html 只能称为 uri)
HTTP是互联网中应用最广泛的应用层协议之一,设计之初是提供一种发布和接收HTML页面的方法,由URI来标识具体的资源。
报文格式
HTTP分别规定了请求和响应的报文格式。
请求报文分为:请求行、请求头(首部行)、请求体(实体主体),GET请求没有实体主体。
响应报文分为:响应行(状态行)、响应头(首部行)、响应体(实体主体)

我们从浏览器或者抓包工具中看起来会像是这样
// 请求头
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
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-line、status-line、header-field、message-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 的响应头信息

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

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

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

Xshell
安全终端模拟软件Xshell,可以直接面向HTTP报文与服务器交互,更清晰、直观地看到请求报文、响应报文的内容。
通过 telnent 建立连接,输入请求头
GET / HTTP/1.1 HOST: localhost: 8000

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

总结
- HTTP 超文本传输协议,在应用层,可以用来获取HTML页面、图片、字体等资源
- ABNF规定了HTTP最严谨的报文格式
- 浏览器、抓包工具、终端模拟工具都可以获取到HTTP的请求报文
以上就是 从ABNF读懂HTTP协议格式的内容 , 更多有关 前端、网络协议 的内容可以参考我其它的博文,持续更新中~
从ABNF读懂HTTP协议格式的更多相关文章
- 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...
- [转帖]从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路 http://www.52im.net/thread-1709-1-2.html 本文原作者阮一峰,作者博客:r ...
- 一泡尿的时间,快速读懂QUIC协议
1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...
- 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议
1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...
- 一文读懂MQTT协议
1 概述 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级 ...
- 详解 WebRTC 传输安全机制:一文读懂 DTLS 协议
作者|进学 审校|泰一 DTLS (Datagram Transport Layer Security) 基于 UDP 场景下数据包可能丢失或重新排序的现实情况下,为 UDP 定制和改进的 TLS 协 ...
- 一文读懂高性能网络编程中的I/O模型
1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...
- 快速读懂 HTTP/3 协议
在 深入浅出:HTTP/2 一文中详细介绍了 HTTP/2 新的特性,比如头部压缩.二进制分帧.虚拟的"流"与多路复用,性能方面比 HTTP/1 有了很大的提升.与所有性能优化过程 ...
- 一文读懂HTTP/2及HTTP/3特性
摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何 ...
- 一文读懂Redis持久化
Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集合.以及散列等,并且还支持多种排序功能. 什么叫持久 ...
随机推荐
- 2021-04-26:整型数组arr长度为n(3 <= n <= 10^4),最初每个数字是<=200的正数且满足如下条件: 1. arr[0] <= arr[1]。2.arr[n-1] <= arr
2021-04-26:整型数组arr长度为n(3 <= n <= 10^4),最初每个数字是<=200的正数且满足如下条件: 1. arr[0] <= arr[1].2.arr ...
- Django4全栈进阶之路17 项目实战(用户管理):user_add.html用户新增画面设计
1.模块: {% extends 'base.html' %} {% block content %} <div class="card mt-3"> <div ...
- 【GiraKoo】Android系统版本代号一览
Android系统版本代号一览 Version CodeName API 时间 13.0 Tiramisu 33 2022.08 12.0 Snow Cone 31,32 2021.10 11.0 R ...
- 【编程日记】搭建python开发环境
0.相关确定 0.1确定操作系统 Python是一种跨平台的编程语言,这意味着它能够运行在所有主要的操作系统中.然而,在不同的操作系统(Windows/Mac/Linux)中,安装Python的方法存 ...
- 关于建立一个Java项目全过程(专对于新手)
关于建立一个Java项目全过程 一.Java开发环境搭建 1.JDK与JRE JDK = JRE + 开发工具集(例如Javac编译工具等) JRE = JVM + Java SE标准类库 2.JDK ...
- 数据科学工具 Jupyter Notebook 教程(一)
ipython notebook 是一个基于浏览器的 python 数据分析工具,使用起来非常方便,具有极强的交互方式和富文本的展示效果.jupyter 是它的升级版,它的安装也非常方便,一般 Ana ...
- 10 款 VS Code 插件神器,第 7 款超级实用!
VS Code 是这两年非常热门的一款 IDE,它不仅有提升开发体验的界面.轻量化的编辑器,还有丰富而强大的插件,这些优秀的插件使得 VS Code 生态体系更加吸引人,让开发效率大大提升.本文来介绍 ...
- Basic Pentesting
来自tryhackme的 Basic Pentesting 开靶场IP:10.10.227.255 # nmap 端口扫描 PORT STATE SERVICE VERSION 22/tcp open ...
- CHS、LAB地址
CHS地址 CHS地址指的是柱面(Cylinder).磁头(Head).扇区(Sector)三个参数组成的地址,是用来表示磁盘上每个扇区位置的一种方式. 物理扇区号 = ((柱面号×磁头数) + 磁头 ...
- 关于int**在malloc为二维数组分配空间时候的作用见解
关于int**在用malloc函数为二维数组分配空间时候 int** 二级指针类型 二维数组的数组名为行指针,写成 arr =(char**)malloc(n*sizeof(char))时,a ...