网络知识详解之:HTTP协议基础
计算机网络相关知识体系详解
- 网络知识详解之:TCP连接原理详解
- 网络知识详解之:HTTP协议基础
- 网络知识详解之:HTTPS通信原理剖析(对称、非对称加密、数字签名、数字证书)
- 网络知识详解之:CA证书制作实战(Nginx数字证书实战)
- 网络知识详解之:网络攻击与安全防护
文章目录
- 网络知识详解之:HTTP协议基础
- HTTP报文
- Debug模式下的HTTP事务
- 报文流动
- 报文的组成部分
- 请求报文格式
- 响应报文格式
- 总结
- HTTP请求
- 起始行
- Headers
- Body
- HTTP响应
- 状态行
- Headers
- Body
- HTTP请求方法
- GET
- HEAD
- PUT
- POST
- TRACE
- OPTIONS
- DELETE
- 状态码
HTTP报文
HTTP 报文是在 HTTP 应用程序之间发送的数据块( 用于 HTTP 协议交互的信息)。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;而消息内容则具有一个类似MIME的格式。这个简单模型是早期Web成功的有功之臣,因为它使开发和部署非常地直截了当。
Debug模式下的HTTP事务
URL:https://leetcode.cn/problemset/all/
Request URL: https://leetcode.cn/problemset/all/
Request Method: GET
Status Code: 200
Remote Address: 203.107.53.81:443
Referrer Policy: strict-origin-when-cross-origin
- Remote Address:访问目标URL解析出来的IP地址,443:表示当前https协议。
- Referrer Policy : Referrer用户指明当前请求的来源页面,对于同源的请求,会发送完整的url作为引用地址,防盗链
Request Headers
:authority: leetcode.cn
:method: GET
:path: /problemset/all/
:scheme: https
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: zh-CN,zh;q=0.9
cache-control: max-age=0
cookie: _bl_uid=7dlyda438j6bn9fby0RO41FhCU9y; gr_user_id=5d9501ad-4549-484f-97e8-33981ae6ca74; a2873925c34ecbd2_gr_last_sent_cs1=jeremy-69; Hm_lvt_fa218a3ff7179639febdb15e372f411c=1672045499,1672930912,1673792504; aliyungf_tc=2ef44e5d8fb43ad2c57272bc57c2a4d0d7e07ae9f8404594e9e8a6f4f957aa61; Hm_lvt_f0faad39bcf8471e3ab3ef70125152c3=1673358708,1673538476,1673787499,1673961406; _gid=GA1.2.1111406179.1673961406; a2873925c34ecbd2_gr_session_id=6f2719a4-dca3-495a-a876-1adb308d601e; a2873925c34ecbd2_gr_last_sent_sid_with_cs1=6f2719a4-dca3-495a-a876-1adb308d601e; a2873925c34ecbd2_gr_session_id_6f2719a4-dca3-495a-a876-1adb308d601e=true; csrftoken=UXAoz5nfsNZ9KMj5xv6vMEK5TaYiLphIBaDVRRuNPZMl9h5vN2yTRHJmCjdRVFhF; _ga=GA1.2.1554241792.1668006538; NEW_PROBLEMLIST_PAGE=1; _ga_PDVPZYN3CW=GS1.1.1673961412.45.1.1673961456.0.0.0; LEETCODE_SESSION=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJfYXV0aF91c2VyX2lkIjoiOTg0MDEwIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiJmNDcwNjFjNzE2ZTRiNDEyZmRhZGE2YWZlNmFmMDVhNzNiMmRmY2E5N2I3YjVkNjhiMjljOWIxNzA5MTIwMzQwIiwiaWQiOjk4NDAxMCwiZW1haWwiOiI3Mzk3NzI4OTNAcXEuY29tIiwidXNlcm5hbWUiOiJqZXJlbXktNjkiLCJ1c2VyX3NsdWciOiJqZXJlbXktNjkiLCJhdmF0YXIiOiJodHRwczovL2Fzc2V0cy5sZWV0Y29kZS5jbi9hbGl5dW4tbGMtdXBsb2FkL3VzZXJzL2plcmVteS02OS9hdmF0YXJfMTYyMzIzNTYyOS5wbmciLCJwaG9uZV92ZXJpZmllZCI6dHJ1ZSwiX3RpbWVzdGFtcCI6MTY3Mzk2MTQ0MC44NTk4NDc4LCJleHBpcmVkX3RpbWVfIjoxNjc2NDg3NjAwLCJ2ZXJzaW9uX2tleV8iOjAsImxhdGVzdF90aW1lc3RhbXBfIjoxNjczOTYyNjkxfQ.ih83fPW5O5u-3kCXvAHWNmyu9YEYiRw29FN-5GSv3GY; Hm_lpvt_f0faad39bcf8471e3ab3ef70125152c3=1673962693; _gat=1; a2873925c34ecbd2_gr_cs1=jeremy-69
if-none-match: "rdtj0nkkz0a30g"
referer: https://leetcode.cn/store/?redeem=remark
sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
- accept:请求可以支持的响应格式列表信息
- accept-encoding:告知服务器本地浏览器支持是压缩方式
- sec-fetch-dest:期望获得什么类型的资源
- sec-fetch-mode :navigate,表示这是一个浏览器的页面切换请求
- sec-fetch-site:表示一个请求发起的来源和目标资源来源之间的关系,crosssite:跨域请求,same-origin:同源请求。
- sec-fetch-user:?1表示的true
- upgrade-insecure-requests :1,表示当前浏览器告诉服务器,浏览器是可以处理https请求的,即使访问的https请求中又包含了其他的http请求。
- user-agent:描述浏览器的信息
Response Headers
cache-control: s-maxage=60, stale-while-revalidate
content-encoding: gzip
content-type: text/html; charset=utf-8
date: Tue, 17 Jan 2023 13:38:16 GMT
etag: "gi13mnk2hfa30c"
strict-transport-security: max-age=31536000
vary: Accept-Encoding
x-nextjs-cache: HIT
x-powered-by: Next.js
- server :web应用程序部署的容器,openresty:封装了Nginx以及第三方的类库,Lua语言,redis等等。
- vary :accept-Encoding,告诉代理服务器缓存两种版本的资源(压缩、不压缩)
报文流动
HTTP 使用术语流入(inbound) 和流出(outbound) 来描述事务处理(transaction)的方向。 报文流入源端服务器, 工作完成之后, 会流回用户的 Agent 代理中。如下图所示,报文流入源端服务器并流回到客户端。
报文的组成部分
HTTP 报文是简单的格式化数据块。 每条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。 它们由三个部分组成:
- 对报文进行描述的起始行(start line)
- 包含属性的首部(header)块
- 以及可选的包含数据的主体(body) 部分
所有的 HTTP 报文都可以分为两类: 请求报文(request message) 和响应报文(response message)。 请求报文会向 Web 服务器请求一个动作。响应报文会将请求的结果返回给客户端。 请求和响应报文的基本报文结构相同。
请求报文格式
- 请求行和请求头都是以
回车符<CR>
+换行符<LF>
作为结束标志,同时在请求头的后面紧跟的是请求空行,这一行仅发送回车符<CR>
+换行符<LF>
,用来表示请求头已发送完成,这样做是因为请求头的个数是不确定的,如果没有加入请求空行,WEB服务器就无法知道请求头到底什么时候结束。 - 并不是所有的请求都有请求体,如
GET
、DELETE
请求是没有请求体的,而POST
、PUT
请求是有请求体的。
响应报文格式
状态码
状态代码元素是一个三位整数代码,它将试图理解和满足请求的结果。状态码由三位数字组成,第一位数字表示响应的类型,常用的状态码有五大类如下表所示:
状态码 | 描述 |
---|---|
1XX | 信息,服务器收到请求,需要请求者继续执行操作 |
2XX | 成功,操作被成功接收并处理 |
3XX | 重定向,需要进一步的操作以完成请求 |
4XX | 客户端错误,请求包含语法错误或无法完成请求 |
5XX | 服务器错误,服务器在处理请求的过程中发生了错误 |
响应头
响应头字段允许服务器传递有关响应的附加信息,而不是状态行中的信息。这些头字段提供有关服务器、进一步访问目标资源或相关资源的信息。
下面将列出一些常见的响应头:
响应头 | 说明 |
---|---|
Access-Control-Allow-Origin | 指定哪些网站可以跨域源资源共享 |
Age | 响应对象在代理缓存中存在的时间,以秒为单位 |
Cache-Control | 通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间,其单位为秒 |
Content-Disposition | 对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开 |
Content-Encoding | 响应资源所使用的编码类型 |
Content-Length | 响应消息体的长度,用8进制字节表示 |
Content-Type | 当前内容的MIME类型 |
Location | 用于在进行重定向,或在创建了某个新资源时使用 |
Set-Cookie | 设置HTTP cookie |
WWW-Authenticate | 表示在请求获取这个实体时应当使用的认证模式 |
响应体
响应体是服务器返回给客户端的文本信息,信息的格式可通过Content-Type
响应头来指定,如常见的text/html
以及前后端使用JSON交换数据时使用的application/json
。
- 对于GET请求方法来说,是直接将表单信息写入到URL当中,要注意URL的长度是有限制的,不同的浏览器和不同的服务器所能接受的最大长度是不一致的,因此要控制请求参数的长度。
- 对于POST请求方式来说,是将表单信息写在请求体中,请求体中的数据格式并不是固定的,只要双方约定好写入数据的格式,服务器就能根据约定解析数据,此外请求体的长度是没有限制的,理论上可以写入任意长度的数据。
总结
HTTP 请求和响应具有相似的结构,由以下部分组成︰
- 一行起始行用于描述要执行的请求,或者是对应的状态,成功或失败,这个起始行总是单行的。
- 一个可选的HTTP头集合指明请求或描述消息正文。
- 一个空行指示所有关于请求的元数据已经发送完毕。
- 一个可选的包含请求相关数据的正文 (比如HTML表单内容),或者响应相关的文档。 正文的大小有起始行的HTTP头来指定。
起始行和 HTTP 消息中的HTTP 头统称为请求头,而其有效负载被称为消息正文
HTTP请求
起始行
HTTP请求是由客户端发出的消息,用来使服务器执行动作。起始行 (start-line)包含三个元素:
-
一个 HTTP 方法,一个动词 ([ GET , PUT 或者 POST ) 或者一个名词 (像 HEAD或者 OPTIONS ), 描述要执行的动作. 例如, GET 表示要获取资源, POST 表示向服务器推送数据 (创建或修改资源)。
-
请求目标 (request target),通常是一个URL,或者是协议、端口和域名的绝对路径,通常以请求的环境为特征。请求的格式因不同的 HTTP 方法而异。它可以是:
-
一个完整的URL,被称为 绝对形式 (absolute form),主要在使用 GET方法连接到代理时使用。
GET http://developer.mozilla.org/enUS/docs/Web/HTTP/Messages HTTP/1.1
-
由域名和可选端口(以 ‘:’ 为前缀)组成的 URL 的 authority component,称为 authority form。 仅在使用 CONNECT 建立 HTTP 隧道时才使用。
CONNECT developer.mozilla.org:80 HTTP/1.1
-
星号形式 (asterisk form),一个简单的星号( ‘*’ ),配合 OPTIONS 方法使用,代表整个服务器。
OPTIONS * HTTP/1.1
-
-
HTTP 版本 (HTTP version),定义了剩余报文的结构,作为对期望的响应版本的指示符。
Headers
来自请求的 HTTP headers遵循和 HTTP header 相同的基本结构:不区分大小写的字符串,紧跟着的冒号 (‘:’) 和一个结构取决于 header 的值。 整个header(包括值)由一行组成,这一行可以相当长。
Body
请求的最后一部分是它的 body。不是所有的请求都有一个 body:例如获取资源的请求,GET,HEAD,DELETE 和 OPTIONS,通常它们不需要 body。 有些请求将数据发送到服务器以便更新数据:常见的的情况是 POST 请求(包含HTML 表单数据)。
HTTP响应
状态行
HTTP 响应的起始行被称作 状态行 (status line),包含以下信息:
-
协议版本,通常为 HTTP/1.1。
-
状态码 (status code),表明请求是成功或失败。常见的状态码是 200 ,404 ,或 302 。
-
状态文本 (status text)。一个简短的,纯粹的信息,通过状态码的文本描述,帮助人们理解该 HTTP 消息。
一个典型的状态行看起来像这样: HTTP/1.1 404 Not Found 。
Headers
响应的 HTTP headers:不区分大小写的字符串,紧跟着的冒号 ( ‘:’ ) 和一个结构取决于 header 类型的值。 整个 header(包括其值)表现为单行形式。
Body
响应的最后一部分是 body。不是所有的响应都有 body。
HTTP请求方法
请求的起始行以方法作为开始, 方法用来告知服务器要做些什么。
下面将列出所有请求方法的名称及描述:
方法名称 | 描述 |
---|---|
GET | GET方法请求一个指定资源的表示形式,使用GET的请求应该只被用于获取数据 |
HEAD | HEAD方法请求一个与GET请求的响应相同的响应,但没有响应体 |
POST | POST方法用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用 |
PUT | PUT方法用请求有效载荷替换目标资源的所有当前表示 |
DELETE | DELETE方法删除指定的资源 |
CONNECT | CONNECT方法建立一个到由目标资源标识的服务器的隧道 |
OPTIONS | OPTIONS方法用于描述目标资源的通信选项 |
TRACE | TRACE方法沿着到目标资源的路径执行一个消息环回测试 |
PATCH | PATCH方法用于对资源应用部分修改 |
GET
GET 是最常用的方法。 通常用于请求服务器发送某个资源。 HTTP/1.1 要求服务器实现此方法。
HEAD
HEAD 方法与 GET 方法的行为很类似, 但服务器在响应中只返回首部,不会返回实体的主体部分。 这就允许客户端在未获取实际资源的情况下, 对资源的首部进行检查。 使用 HEAD, 可以:
- 在不获取资源的情况下了解资源的情况(比如, 判断其类型) ;
- 通过查看响应中的状态码, 看看某个对象是否存在;
- 通过查看首部, 测试资源是否被修改了
服务器开发者必须确保返回的首部与 GET 请求所返回的首部完全相同。 遵循HTTP/1.1 规范, 就必须实现 HEAD 方法。
PUT
与 GET 从服务器读取文档相反, PUT 方法会向服务器写入(更新)文档。
PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的 URL 命名的新文档, 或者, 如果那个 URL 已经存在的话, 就用这个主体来替代它,一般更新操作时会使用PUT请求方法。
POST
POST 方法起初是用来向服务器输入数据的 。 实际上, 通常会用它来支持HTML的表单。 表单中填好的数据通常会被送给服务器处理。
TRACE
TRACE客户端发起一个请求时, 这个请求可能要穿过防火墙、 代理、 网关或其他一些应用程序。 每个中间节点都可能会修改原始的 HTTP 请求。 TRACE 方法允许客户端在最终将请求发送给服务器时, 看看它变成了什么样子。TRACE 请求会在目的服务器端发起一个“环回” 诊断。 行程最后一站的服务器会弹回一条TRACE 响应, 并在响应主体中携带它收到的原始请求报文。 这样客户端就可以查看在所有中间 HTTP 应用程序组成的请求 / 响应链上, 原始报文是否, 以及如何被毁坏或修改过
TRACE 方法主要用于诊断。也就是说, 用于验证请求是否如愿穿过了请求 / 响应链。
OPTIONS
OPTIONS 方法请求 Web 服务器告知其支持的各种功能。 可以询问服务器通常支持哪些方法, 或者对某些特殊资源支持哪些方法。
DELETE
DELETE 方法所做的事情就是请服务器删除请求 URL 所指定的资源。
状态码
方法是用来告诉服务器做什么事情的, 状态码则用来告诉客户端,事情执行的结果。状态码位于响应的起始行中。 服务器通常会返回一个数字状态和一个可读的状态。 数字码便于程序进行差错处理, 而原因短语则更便于人们理解。
- 200 到 299 之间的状态码表示成功。
- 300 到 399 之间的代码表示资源已经被移走
- 400 到 499 之间的代码表示客户端的请求出错