注:本文为 "HTTP 历史 | 协议报文结构 | 返回状态码" 相关文章合辑。
未去重整理。
HTTP 历史
wangjunliang 最后更新: 2024/3/16 上午10:29
超文本传输协议 (英语:H yperT extT ransferP rotocol,缩写:HTTP )是 万维网(World Wide Web)的基础协议。自 蒂姆・伯纳斯-李(Tim BernersLee)博士和他的团队在 1989-1991 年间创造出它以来,HTTP 已经发生了太多的变化,在保持协议简单性的同时,不断扩展其灵活性。如今,HTTP 已经从一个只在实验室之间交换文档的早期协议进化到了可以传输图片,高分辨率视频和 3D 效果的现代复杂互联网协议。
HTTP 的诞生
1989 年 3 月 [欧洲核子研究组织](https://zh.wikipedia.org/wiki/ 歐洲核子研究組織)(CERN)的 [蒂姆・伯纳斯 - 李 ](https://zh.wikipedia.org/wiki/ 提姆・柏內茲 - 李)(Tim BernersLee)博士提出了一种能让远隔两地的研究者们共享知识的设想。 最初设想的基本理念是:借助多文档之间相互关联形成的超文本(HyperText),连成可相互参阅的 WWW(World Wide Web,万维网)。
蒂姆最初的提议。图片来源:欧洲核子研究中心
到 1990 年 10 月,Tim 编写了三项基本技术来实现设想,这些技术仍然是当今网络的基础(您可能已经在网络浏览器的某些部分上看到过这些技术):
-
HTML(HyperText Markup Language):超文本标记语言,作为编写文档的语言。
-
HTTP(HyperText Transfer Protocol):超文本传输协议,作为传递文档的协议。
-
URL(Uniform Resource Locator):统一资源标识符,一种唯一的 "地址",用于标识文档在网络上的位置。
此外 Tim 还编写了第一个网页编辑器 / 浏览器("WorldWideWeb.app")和第一个 Web 服务器("httpd")。至此 Tim 初步完成了他的设想的所有技术实现,且第一批服务器已经在 1991 年初在 CERN 以外的地方运行了,1991 年 8 月 16 日,Tim Berners-Lee 在公开的超文本新闻组上 发表 的文章被视为是万维网公共项目的开始。
对于 HTTP 而言, 在应用的早期阶段它是非常简单的,后来它也被称为 HTTP/0.9,有时也叫做单行 hang(one-line)协议。
HTTP/0.9------ 单行协议 (1991)
最初版本的 HTTP 协议并没有版本号,后来它的版本号被定位在 0.9 以区分后来的版本。HTTP/0.9 于 1991 年提出。它是有史以来最简单的协议;它的请求由单行指令构成(因此也称为单行协议),以唯一可用方法 GET
开头,其后跟目标资源的路径(一旦连接到服务器,协议、服务器、端口号这些都不是必须的)。
http
GET /index.html
响应也极其简单的:只包含 HTML 文档本身。
html
<HTML>
这是一个非常简单的 HTML 页面
</HTML>
跟后来的版本不同,HTTP/0.9 的响应内容并不包含 HTTP 头。这意味着只有 HTML 文件可以传送,无法传输其他类型的文件。也没有状态码或错误代码。一旦出现问题,一个特殊的包含问题描述信息的 HTML 文件将被发回,供人们查看。
特性
-
它是 ASCII 协议,请求 / 响应都是由 ASCII 字符组成字符串。
-
它在 TCP/IP 链路上运行。
-
请求以回车符 (CRLF) 终止。
-
响应只包含 HTML 文档。
-
文档传输完成后,TCP 连接将终止。
缺陷
-
只支持 GET 请求: HTTP/0.9 仅支持 GET 方法,意味着只能用于获取资源,不能用于其他类型的请求,如 POST、PUT、DELETE 等。这导致在处理复杂的应用逻辑和实现数据更新等操作时,HTTP/0.9 显得非常有限。
-
只能传输 HTML: HTTP/0.9 的响应只能包含 HTML 文档,无法处理其他类型的数据,如 JSON、XML、图像等。这限制了其在处理现代 Web 应用程序中的数据传输和交互能力。
-
无法进行内容协商: HTTP/0.9 没有头部信息,无法携带元数据,如 Content-Type、Content-Length 等,这使得它无法识别并正确解析其他响应内容。
-
没有状态码或错误代码: 也是由于 HTTP/0.9 没有头部信息,无法携带元数据,因此响应成功与失败都是返回 HTML 文档,这使得浏览器不能知晓请求执行成功或失败,并相应调整行为。
-
不支持持久连接: 在 HTTP/0.9 中,每次请求都会建立一个新的 TCP 连接,请求完成后立即关闭连接。这导致在处理大量请求时,频繁地建立和关闭连接会带来较大的开销,影响性能。
-
安全性问题: HTTP/0.9 没有提供任何加密和安全机制,所有的数据都是明文传输。这使得数据容易受到窃听和篡改,缺乏对隐私和数据完整性的保护。
-
只能传输英文文本数据: HTTP/0.9 默认采用的字符集是 ASCII 字符集,这意味着 HTTP 只能传输英文文本数据,无法支持其他语言的文本数据,比如包含非英文字符的文本(如中文、日文、俄文等)。
正如你们所看到的,HTTP/0.9 仅适用于简单的、仅需要获取 HTML 文档的场景。新兴 Web 所需功能及其在公共 Web 上的用例不断增长,很快就强化了 HTTP 0.9 的许多缺陷:我们需要一个协议,该协议不仅可以服务于超文本文档,还可以提供有关请求和响应的更丰富的元数据。
很快,HTTP 的下一个版本(即 HTTP/1.0)被推出,它解决了 HTTP/0.9 的缺陷,并提供更多强大的功能和性能优化。
HTTP/1.0------ 构建可扩展性 (1996)
1996 年 5 月,HTTP 工作组 (HTTP-WG) 发布了 RFC 1945,文档 RFC 1945 定义了 HTTP/1.0,但它是狭义的,并不是官方标准。
HTTP/1.0 通过定义了 HTTP 请求 / 响应的结构,加入许多头部信息,现在可以处理其他响应格式,即图像、视频文件、纯文本或任何其他内容类型。它添加了更多方法(即 POST 和 HEAD)、添加了状态代码来标识响应、引入了字符集、类型、授权、缓存、内容编码等内容。
以下为 HTTP/1.0 的请求示例:
http
GET / HTTP/1.0
Host: cs.fyi
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
以下为 HTTP/1.0 的响应示例:
http
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
(response body)
(connection closed)
HTTP/1.0 的请求与响应现在看起来也是非常熟悉的,因为它首次定义了请求 / 响应的格式我们沿用至今,并且由于加入头信息,使得内容协商变得容易起来,这也极大的丰富了它的扩展性,虽然请求和响应标头仍保留为 ASCII 编码,但响应正文可以是任何类型,即图像、视频、HTML、纯文本或任何其他内容类型。因此,现在服务器不仅仅只能向客户端发送 HTML 文档,还可以发送其他任何内容类型;推出后不久,HTTP 中的 "超文本" 一词就变得用词不当。HMTP 或超媒体传输协议可能更有意义,但我想,我们终生都坚持这个名字。
请求与响应头仍是 ASCII 编码,那么其中的中文是如何处理的呢?
我们都知道 ASCII 编码仅表示了英文小大写、数字以及一些标点符号,对于其他国家的语言是并不支持的,那么请求头中的其他国家的语言的信息如何处理呢?
我尝试使用浏览器访问以中文命名的 HTML,URL:wangjunliang.com/我想看看.html
http
请求网址:
https://www.wangjunliang.com/% E6%88%91% E6%83% B3% E7%9C%8B% E7%9C%8B.html
请求方法:
GET
状态代码:
200
远程地址:
127.0.0.1:7890
引荐来源网址政策:
strict-origin-when-cross-origin
惊奇的发现在请求头中 我想看看
转换为了 %E6%88%91%E6%83%B3%E7%9C%8B%E7%9C%8B
,这就是传说中的 URL 编码。
URL 编码: URL 编码是一种将特殊字符和非 ASCII 字符转换为 ASCII 字符的方法,使它们能够在 HTTP 请求的 URL 中进行传输。具体而言,URL 编码使用 "%" 符号后跟两个十六进制数字来表示一个字符。例如,中文字符 "中" 的 URL 编码表示为 "% E4% B8% AD"。这个编码表示了字符 "中" 在 ASCII 字符集中的十六进制表示。当 HTTP/1.0 的请求或响应中包含中文字符时,这些字符会被转换成对应的 URL 编码形式。服务器收到 URL 编码后的请求后,会将其还原为原始的中文字符进行处理。需要注意的是,HTTP/1.0 的 URL 编码仅适用于 URL 中的字符编码。
神奇的 base64------ 在 ASCII 上传输任何内容
在 HTTP 的早期版本,如 HTTP/0.9 和 HTTP/1.0,由于对字符集的限制以及内容协商机制缺失与不完善,直接传输二进制数据或非 ASCII 字符是有挑战的。为了在这些早期版本的 HTTP 中传输图片或其他二进制数据,人们使用了将二进制数据转换为 ASCII 字符的编码方式 ------base64。
base64 编码: 是一种将二进制数据转换成 ASCII 码中 64 个字符(A-Z、a-z、0-9 和 +、/ 两个符号)的文本编码方式。
在 Base64 编码中,原始二进制数据每 3 个字节的二进制数据被分成 4 组,每组 6 位,然后分别转换成 4 个 ASCII 字符。也就是说原始数据每 6 位将会被转换成一个 ASCII 字符,而一个 ASCII 字符占用空间则是 8 位,因此编码后的数据大小会增加约 1/3
原始数据 (占用空间:24 位) | base64 编码 | 编码后二进制数据 (占用空间:32 位) |
---|---|---|
100100 101001 100100 101001 | kpkp | 01101011 01110000 01101011 01110000 |
如果待编码的二进制数据长度不是 3 的倍数,Base64 编码会在末尾添加 1 或 2 个填充字符 "=",以确保编码后的文本长度是 4 的倍数。这进一步增加了数据的大小。
特性
-
定义了请求 / 响应格式: HTTP/1.0 将请求 / 响应格式划分为了三个部分 ------ 起始行、头部信息、消息体,这个格式一直沿用至今。
-
加入了状态码和状态描述: 在响应的起始行中加入了状态代码和状态的描述信息,提供了关于请求处理结果的信息,以便客户端和服务器能够进行适当的处理和决策。
-
加入了内容协商: 虽然在 HTTP/1.0 中起始行与头部信息都保留为 ASCII 编码,但它通过加入了 Content-Type、Content-Length、Transfer-Encoding 等头部属性,可以对不同类型的文件在消息体中进行不同的编码。也就是说起始行、头部信息传输仍是 ASCII 编码,而消息体则会根据头部属性让客户端 / 服务器进行内容协商,进行不同的编码方式。
-
可以传输任何文件: 由于 HTTP/1.0 加入了内容协商的机制,使得只要客户端 / 服务器协商一致,HTTP/1.0 就可以传输任何形式的文件。
-
新增 POST、HEAD 请求: POST 请求方法允许客户端向服务器提交数据,而 HEAD 请求方法允许客户端获取资源的元数据。这些新增的请求方法丰富了 HTTP 协议的能力,使得客户端和服务器能够进行更多样化的交互和处理。
-
不再只是传输英文文本数据: HTTP/1.0 引入字符集(Character Set),解决了其他国家语言文本数据的字符编码问题,并确保文本数据能够以正确的方式被处理和显示。
-
初步引入缓存概念: HTTP/1.0 引入了头部字段如 Expires 和 Last-Modified,用于控制缓存的行为,以及头部字段如 If-Modified-Since 和 If-None-Match,用于条件性请求。
-
初步引入持久链接: HTTP/1.0 引入一个名为 Connection: keep-alive 的新标头,来保持请求建立起来的 TCP 连接,以供后续请求继续使用该链接完成请求。
-
初步引入代理支持: HTTP/1.0 引入了 Proxy-Connection 头部字段来指示代理服务器是否应保持持久连接,并引入了 Via 头部字段,用于标识请求经过的代理服务器链。
缺陷
-
持久链接未得到广泛支持,默认仍为短连接: HTTP/1.0 的尝试通过引入一个名为 Connection: keep-alive 的新标头来克服短连接问题,但它仍然没有得到广泛的支持,问题仍然存在。
-
请求阻塞: 在 HTTP/1.0 中,每个请求都需要按照顺序进行,即必须等待前一个请求的响应返回后才能发送下一个请求。如果前一个请求很耗时,会导致后续请求被阻塞,影响并发性能。
-
无状态: HTTP 是一种无状态协议,即服务器不维护有关客户端的信息,当客户端需要记录状态时,必须发送一些记录状态的冗余数据,从而导致带宽使用量增加。
-
缺乏压缩支持: HTTP/1.0 没有内置的数据压缩机制,因此在传输大量文本数据时,没有有效地压缩数据,增加了网络传输的开销。
-
安全性问题: HTTP/1.0 没有提供任何加密和安全机制,所有的数据都是明文传输。这使得数据容易受到窃听和篡改,缺乏对隐私和数据完整性的保护。
-
实现混乱: 由于 HTTP/1.0 并不是官方标准,许多浏览器厂商并没有按照 HTTP/1.0 的指导实现 HTTP,导致在实际运用中混乱不堪。
可以看到对于 HTTP/0.9 人们诟病的是它的文件类型支持不够丰富,由于它的文件类型支持不丰富,所有通常只是请求 HTML 文档,往往发送一次请求就能获取到完整的内容。而在 HTTP/1.0 丰富了文件类型后,一次请求不再能获取到全部内容,并且请求的内容也从较小的 HTML 文档发展到了图片、音频、视频等较大的文件,此时 HTTP 的性能问题也被暴露出来。
此外,由于各个浏览器相互竞争,各自为战,并且 HTTP/1.0 并不是官方标准,只是一些指导意见。这导致各个厂商对于 HTTP 都有各自的实现方式,导致在实际运用中混乱不堪。
由于上述原因,人们迫切需要优化 HTTP 性能,制定一份标准化 HTTP 协议!
HTTP/1.1------ 标准化的协议 (1997)
HTTP/1.0 多种不同的实现方式在实际运用中显得有些混乱。自 1995 年开始,即 HTTP/1.0 文档发布的下一年,就开始修订 HTTP 的第一个标准化版本。 在 1997 年 1 月 HTTP1.1 标准以 RFC 2068 文件发布,后续 HTTP/1.1 协议进行过两次修订,分别是 RFC 2616 发布于 1999 年 6 月,以及 RFC 7230-RFC 7235 发布于 2014 年 6 月。
HTTP/1.1 标准消除了早期版本中大量歧义内容,并引入了许多关于性能优化的措施:持久链接、管道化技术、支持范围请求和部分响应、分块传输机制、明确缓存控制机制、增加压缩技术、增强内容协商机制、增加客户端 cookie 等。除了改进 HTTP 性能方面 HTTP/1.1 还新增状态码、引入了基本认证和摘要认证,提供更强大的用户认证机制,确保更安全的通信、 引入了 Host 头字段,该字段允许在同一个物理服务器上托管多个域名。这使得虚拟主机能够通过在 Host 头中指定域名来区分不同的网站、并且它还新增了许多请求方法,极大丰富了请求类型。
以下为HTTP/1.1 的请求示例
http
GET /zh-CN/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/Simple_header
以下为HTTP/1.1 的响应示例
http
200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
我们可以看到在请求 / 响应格式上 HTTP/1.1 与 HTTP/1.0 并无差异,这是因为 HTTP/1.1 沿用了 HTTP/1.0 的请求 / 响应格式。
特性
-
持久化连接: 在 HTTP/1.0 中持久连接默认为关闭,并没有得到广泛应用,而在 HTTP/1.1 中连接默认情况下不会关闭,而是保持打开状态,从而允许多个顺序请求。要关闭连接,请求头 Connection: close 必须可用。客户端通常在最后一个请求中发送此标头以安全地关闭连接。
-
管道化技术: HTTP/1.1 引入了管道化技术,以解决请求阻塞问题,客户端可以在同一连接上向服务器发送多个请求,而无需等待服务器的响应,并且服务器必须按照接收请求的顺序发送响应。
-
新增客户端 Cookie: 由于 HTTP 是无状态协议,当客户端需要记录状态时,必须发送一些记录状态的冗余数据,从而导致带宽使用量增加。HTTP/1.1 引入了客户端 cookie 以解决该问题,通过在浏览器中设置 cookie,服务器可以跟踪用户会话状态,实现用户身份认证,个性化用户体验等。
-
新增 Gzip、Deflate 等压缩技术: 在 HTTP/1.1 中,服务器可以使用 Gzip、Deflate 等压缩算法来压缩 HTTP 响应的实体主体部分(如 HTML、CSS、JavaScript 等),然后在响应头中使用 "Content-Encoding" 字段来指示客户端该响应已经被压缩以及压缩的算法。客户端收到压缩的响应后,会自动解压缩以获取原始内容。
-
引入了基本认证和摘要认证机制: 在 HTTP/1.1 中,可以通过基本认证和摘要认证机制,在请求头中传递用户名和密码等凭据进行用户身份验证。
-
引入了范围请求和部分响应机制: HTTP/1.1 引入了范围请求和部分响应的功能,通过在 HTTP 请求头中使用 "Range" 字段指定所需的资源范围,而服务器在响应头中使用 "206 Partial Content" 状态码表明返回的是部分响应,并通过 "Content-Range" 字段指示返回内容的字节范围。这使得客户端可以请求大文件的特定部分,例如断点续传的情况下,从而避免重新下载整个文件。此外,范围请求还能让客户端只获取媒体资源的特定片段,优化数据传输并提升用户体验。
-
引入了分块传输机制: HTTP/1.1 引入了分块传输(Chunked Transfer Encoding)机制,用于在动态内容传输时,服务器无法提前确定整个内容的长度的情况下,逐块发送内容。在分块传输中,服务器将响应拆分为一系列块,每个块都有一个独立的大小,并使用 "Transfer-Encoding: chunked" 请求头来通知客户端有关分块传输的信息。客户端接收到该头信息后,知道响应将以分块的形式传输,它可以按照指定的块大小逐块接收内容,直到接收到一个长度为零的块,表示传输已完成。这种机制适用于动态生成内容、流式传输以及服务器长时间运行的响应等场景,提供了更灵活和高效的数据传输方式。
-
明确缓存机制: HTTP/1.1 在 HTTP/1.0 的基础上进一步明确了缓存机制,服务器可以通过设置响应头字段来控制缓存行为,例如使用 "Cache-Control" 头字段来指定缓存策略,如 "max-age" 用于设置资源的最大缓存时间,"no-cache" 用于要求客户端验证资源的有效性等。同时,服务器也可以在响应头中添加 "Expires" 头字段,设置资源的过期时间,以便客户端在接收到资源后在过期时间之前可以直接使用缓存的副本。另外,HTTP/1.1 还支持 "Last-Modified" 和 "If-Modified-Since" 头字段,以及 "ETag" 和 "If-None-Match" 头字段,用于在客户端缓存资源后,再次请求时验证资源是否已经发生变化,如果未变化,服务器返回 304 Not Modified 状态码,让客户端使用缓存的资源,从而避免重复传输。通过这些头字段的灵活组合使用,HTTP/1.1 的缓存机制实现了更高效、可控的缓存管理,优化了 Web 应用程序的性能和用户体验。
-
增强内容协商机制: HTTP/1.1 增加了 Accept-Language、Accept-Encoding 和 Accept-Charset 等头字段,允许客户端明确指定其首选语言、内容编码方式和字符集,让服务器能够更好地提供适配客户端需求的内容。此外,HTTP/1.1 还引入了 Vary 头字段,用于标明服务器响应可能因客户端请求头的不同而变化,这样确保代理服务器能够存储和提供正确的缓存内容。这些改进使得 HTTP/1.1 的内容协商机制更加强大和智能,提高了资源传输的效率和用户体验。
-
添加了新的 HTTP 方法: HTTP/1.1 新增了 PUT、PATCH、OPTIONS、DELETE 方法。
-
新增了 Host 头字段: TTP/1.1 引入了 Host 头字段,该字段允许在同一个物理服务器上托管多个域名。这使得虚拟主机能够通过在 Host 头中指定域名来区分不同的网站。
-
新增了状态码
缺陷
-
线头阻塞(Head-of-Line Blocking): HTTP/1.1 在同一连接上使用持久连接,但由于串行发送请求和响应,如果一个请求或响应的处理时间较长,那么后续的请求和响应将被阻塞,为此它引入了管道化技术 (pipelining) 试图解决该问题,但它并没有完全解决这个问题,因为即使在客户端请求选择某一管道并被异步发送出去,但在服务器如果该请求前面存在缓慢或繁重的请求,那么该请求就会被阻塞。这种情况也被称为线头阻塞
-
无法处理较多的并发请求: 由于头阻塞问题和单个连接的限制,HTTP/1.1 在处理较多的并发请求时表现较差。浏览器限制了同时与同一域名建立的连接数,针对同一域名的并发请求最多可以同时发送 6 到 8 个,如果有超过限制的请求需要发送,浏览器会将这些请求放入队列,从而限制了并发请求的数量。
-
未能被充分利用的 TCP: HTTP 1.1 很难榨干 TCP 协议所能提供的所有性能。HTTP 客户端和浏览器必须要另辟蹊径的去找到新的解决方案来降低页面载入时间。
-
明文传输: HTTP/1.1 默认是明文传输,数据在网络上传输时不加密,可能被窃听或篡改。这会导致安全隐患,尤其是对于敏感信息的传输。
-
头部冗余: HTTP/1.1 的请求和响应头部会携带一些冗余的信息,导致了较大的头部开销,特别是对于小的资源请求。
-
没有对头字段进行压缩: HTTP/1.1 没有对头字段进行压缩,尽管 HTTP 响应的主体可以使用 Gzip 等压缩算法,但头字段仍然是明文传输,可能在一些情况下浪费带宽。
-
请求 - 响应模式: HTTP/1.1 使用请求 - 响应模式,每个请求需要等待响应后才能继续。这种模式对于实时性要求较高的应用场景,如实时通信和流媒体,效率较低。
-
缺乏推送功能: HTTP/1.1 缺乏服务器主动向客户端推送资源的机制。客户端只能通过不断发送请求来获取资源,这导致了一定的延迟和额外的开销。
超过 25 年的逐步扩展
从 HTTP/1.1 协议发布至今,HTTP/1.1 协议已稳定使用超过 25 年,目前大部分网站仍是基于 HTTP/1.1 来运行的。这期间 HTTP/1.1 也做了多次扩展与修改,并发展不同的应用模式,以弥补之前的缺陷以及满足日益进步的需求。
HTTP 用于安全传输
在 1994 年,网景通信公司(Netscape Communications Corporation)为了解决当时互联网上数据传输的安全问题,发布了第一个安全套接字层(Secure Sockets Layer,SSL)协议。SSL 协议使用了加密技术,对 HTTP 的数据进行加密传输,保护数据的安全性。
在 SSL 协议的基础上,网景通信公司将安全传输的功能整合到 HTTP 协议中,形成了 HTTPS 协议。HTTPS 使用了 SSL/TLS(Transport Layer Security)协议来加密 HTTP 传输过程中的数据,使得网站和用户之间的通信不再以明文传输,变得安全。
HTTP 用于复杂应用
在 2000 年,一种新的使用 HTTP 的模式被设计出来:具象状态传输(representational state transfer) (或者说 REST)。由 API 发起的操作不再通过新的 HTTP 方法传达,而只能通过使用基本的 HTTP / 1.1 方法访问特定的 URI。这允许任何 Web 应用程序通过提供 API 以允许查看和修改其数据,而无需更新浏览器或服务器。所有需要的内容都被嵌入到由网站通过标准 HTTP/1.1 提供的文件中。REST 模型的缺点在于每个网站都定义了自己的非标准 RESTful API,并对其进行了全面的控制。RESTful API 在 2010 年变得非常流行。
自 2005 年以来,可用于 Web 页面的 API 大大增加,其中几个 API 为特定目的扩展了 HTTP 协议,大部分是新的特定 HTTP 头:
-
Server-sent events,服务器可以偶尔推送消息到浏览器。
-
WebSocket,一个新协议,可以通过升级现有 HTTP 协议来建立。
SPDY------Google 的尝试 (2009)
这些年来,网页愈渐变得的复杂,甚至演变成了独有的应用,可见媒体的播放量,增进交互的脚本大小也增加了许多。 如果仔细观察当前的一些网站所需要下载的资源的话,会发现一个非常明显的趋势 ------ 近年来加载网站首页需要的下载的数据量在逐渐增加,平均每个页面为了完成显示与渲染所需要下载的资源数已经超过了 100 个。HTTP/1.1 链接需要请求以正确的顺序发送,理论上可以用一些并行的链接(尤其是 5 到 8 个),带来的成本和复杂性堪忧。比如,HTTP 管线化(pipelining)就成为了 Web 开发的负担。HTTP 1.1 很难榨干 TCP 协议所能提供的所有性能。HTTP 客户端和浏览器必须要另辟蹊径的去找到新的解决方案来降低页面载入时间。与此同时,人们也尝试去用新的协议来替代 TCP,但结果证明这也非常困难。无奈之下,我们只能尝试同时改进 TCP 协议本身和基于 TCP 的上层协议。
在 2010 年早期,谷歌通过实践了一个实验性的 SPDY 协议,想要以此来解决当前 HTTP 存在的问题。SPDY 的功能包括多路复用、压缩、优先级、安全性等。本节不打算详细介绍 SPDY,因为我们在下一节中深入了解 HTTP/2 的本质时,您就会明白了,HTTP/2 主要是受到 SPDY 的启发。
在 2015 年,Google 决定将 SPDY 协议与 HTTP 合并,并基于 SPDY 的特点推出了 HTTP/2。通过将 SPDY 融入 HTTP/2,Google 希望避免存在两个竞争的标准,统一标准有利于更好地推动 Web 协议的发展。同时,Google 宣布 SPDY 协议被废弃,不再继续作为一个独立的协议存在,HTTP/2 成为了 SPDY 的继任者,并继续在未来发展和推广。
HTTP/2------ 更优异的性能 (2015)
由于 HTTP/1.1 发展年限久远,用户数量庞大,因此对于 HTTP/1.1 的升级需要制定非常严格的边界与观念,这也给小组成员的创新带来了一些许限制。
升级的边界与观念
- 必须保持早期 HTTP 的标准范式: 由于 HTTP/1.1 使用年限久远,用户数量庞大,使用该协议的网站太多了,如果改动过大且费力,这肯定会阻碍 HTTP/2.0 发展。因此 HTTP/2.0 必须保留所有现有的接口、内容、URI 格式和结构, 不需要站点和应用做出改变,拥有一个最新的服务器和新点的浏览器即可升级 HTTP/2.0。
如上所述,现有的 URI 结构正在被 HTTP 1.x 使用而不能被更换,所以 http2 也必须沿用该结构。因此不得不找到一种方式将使用的协议升级至 http2
HTTP 1.1 本身就制定过 "升级" 的方案:提供一个首部字段,表示允许服务器在收到旧协议请求的同时,可以向客户端发送新协议的响应。但这一方案往往需要花费一次额外的往返通信来作为升级的代价。
而这一代价是 SPDY 团队不想接受的。因为他们只实现了基于 TLS 的 SPDY,所以他们开发了一个 TLS 的扩展去简化协议的协商。这个扩展被称作 NPN(Next Protocol Negotiation),借助于此,服务器会通知客户端所有它支持的协议,让客户端从中选择一个合适的来进行通讯。
-
提供 HTTP1 到 http2 服务器的代理: HTTP1 的服务器和客户端仍然会长期存在,所以我们必须提供 HTTP/1 到 http2 服务器的代理,并且这种代理能够将 http2 的功能一对一的映射到 HTTP 1.1 的客户端。
-
不再使用小版本号: 服务器和客户端都必须确定自己是否完整兼容 http2 或者彻底不兼容。如果将来该协议需要被扩充或者变更,那么新的协议将会是 http3,而不是 http 2.x。
-
降低协议对延迟的敏感
-
修复 HTTP/1.1 中 pipelining 和 head of line blocking 的问题
-
防止主机需求更高的连接数量
在确认好升级边界与观念后,HTTP/2 协议规范(RFC 7540)于 2015 年 5 月发表,HTTP/2 解决了 HTTP/1 中存在的一大堆缺点,其中相当一部分对于开发者来说非常麻烦,在 HTTP/2 出现前,开发者要用许多种变通方法来解决。
在 HTTP/2.0 中 HTTP 从一个 ASCII 协议变为一个二进制协议,其主要特性是多路复用(multiplexing),它可以通过同一个 TCP 连接发送多个逻辑数据流。复用使得很多事情变得更快更好,它带来更好的拥塞控制、更充分的带宽利用、更长久的 TCP 连接 ------------ 这些都比以前更好了,链路能更容易实现全速传输,标头压缩技术也减少了带宽的用量。采用 HTTP/2 后,浏览器对每个主机一般只需要 一个 TCP 连接,而不是以前常见的 六个 连接。事实上,HTTP/2 使用的连接聚合(connection coalescing)和 "去分片"(desharding)技术还可以进一步缩减连接数。HTTP/2 还解决了 HTTP 的队头拥塞(head of line blocking)问题,客户端必须等待一个请求完成才能发送下一个请求的日子过去了。
以下为HTTP/2 的请求示例
http
GET /zh-CN/docs/Glossary/Simple_header HTTP/2
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/Simple_header
以下为HTTP/2 的响应示例
http
200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
大家可以惊奇的发现,除了版本号,HTTP/2.0 与 HTTP/1.1 在内容与格式上几乎没有任何差别!这得益于早期标准制定者对 HTTP/1.1 升级边界与观念的思考,这让标准制定者几乎保留了 HTTP/1.1 内容与形式上的所有标准,从修改 HTTP 底层技术来解决 HTTP/1.1 中的缺点。
也正因如此,HTTP/2.0 不需 Web 开发者做什么,不需要站点和应用做出改变,随着陈旧的浏览器和服务器的更新,站点自然就会升级到 HTTP/2.0 而不会带来任何问题,并且还能在数据传输上节省了可观的成本和支出,这使得该协议在互联网和万维网上得到广泛的实现和部署,HTTP/2.0 取得了巨大的成功。
特性
-
HTTP/2.0 是一个二进制协议: 在 HTTP/2.0 中,HTTP 不再是 ASCII 协议,而是二进制协议。作为一个二进制协议,它更容易解析,但与 HTTP/1.x 不同的是,它不再被人眼读取。HTTP/2 的主要构建块是帧和流,每个 HTTP/2 请求和响应都被赋予一个唯一的流 ID,并且它被分成帧。帧不过是二进制数据,帧的集合称为流。每个帧都有一个流 ID,用于标识它所属的流,并且每个帧都有一个公共标头(Type, Length, Flags, Stream Identifie)和帧有效负载,规范中一共定义了 10 种不同的帧,其中最基础的两种分别对应于 HTTP 1.1 的 DATA 和 HEADERS。此外,流 ID 是唯一的,客户端发起的任何请求流 ID 都使用奇数,而来自服务器的响应流 ID 则都是偶数。
-
多路复用: 由于 HTTP/2 现在是二进制协议,并且正如我上面所说,它使用帧和流来进行请求和响应,因此一旦打开 TCP 连接,所有流都会通过同一连接异步发送,而无需打开任何其他连接。反过来,服务器以相同的异步方式响应,即响应没有顺序,客户端使用分配的流 ID 来识别特定数据包所属的流。流的多路复用解决了 HTTP/1.x 中存在的线头阻塞问题,即客户端不必等待正在花费时间的请求,其他请求仍将得到处理。
-
流优先级(Stream Prioritization): HTTP/2 允许对请求 / 响应进行优先级排序,每个流都包含一个优先级(也就是 "权重"),它被用来告诉对客户端哪个流更重要。当资源有限的时候,服务器会根据优先级来选择应该先发送哪些流。借助于借助于 PRIORITY 帧,客户端同样可以告知服务器当前的流依赖于其他哪个流,该功能让客户端能建立一个优先级 "树",所有 "子流" 会依赖于 "父流" 的传输完成情况。优先级和依赖关系可以在传输过程中被动态的改变。这样当用户滚动一个全是图片的页面的时候,浏览器就能够指定哪个图片拥有更高的优先级。或者是在你切换标签页的时候,浏览器可以提升新切换到页面所包含流的优先级。优先级的引入确保重要资源的优先加载,提高了页面加载速度和用户体验。
-
头部压缩: HTTP 是一种无状态的协议。简而言之,这意味着每个请求必须要携带服务器需要的所有细节,而不是让服务器保存住之前请求的元数据,这导致许多请求和响应头部会携带一些冗余的一摸一样的信息,增大了标头大小,致使带宽使用和延迟增加。为了克服这个问题,HTTP/2 使用 HPACK 算法对头部信息进行压缩,减少了头部大小,从而降低了传输的数据量,提高了效率。
-
服务器推送: HTTP/2 的服务器推送功能允许服务器在客户端请求前主动推送资源。服务器可以通过发送一个名为 PUSH_PROMISE 的特殊帧,通知客户端即将推送的资源。这个 PUSH_PROMISE 帧与导致推送发生的流相关联,并包含服务器将要推送的资源的流 ID。通过服务器推送,服务器可以在客户端请求之前主动将客户端可能需要的资源发送到客户端缓存中,从而避免了客户端额外的请求,减少了延迟。这种特性在某些情况下可以提高页面加载速度和性能,尤其是对于一些预加载资源或常用资源,可以减少客户端请求的往返次数,优化了 Web 应用的性能和用户体验。
-
中断连接不再断开连接: HTTP/1.1 协议有一个缺点:当一个含有确切值的 Content-Length 的 HTTP 消息被送出之后,你就很难中断它了。当然,通常你可以断开整个 TCP 链接(但也不总是可以这样),但这样导致的代价就是需要通过三次握手来重新建立一个新的 TCP 连接。在 http2 里面,我们可以通过发送 RST_STREAM 帧来实现这种需求,它是一种特殊的帧类型,用于中止某些流,即客户端可以发送此帧让服务器知道我不需要此流了。客户端可以使用 RST_STREAM 并停止接收特定流,同时连接不会被关闭其他流仍会正常运行。
-
可靠性和安全性: HTTP/2 支持数据的流量控制和优先级设置,保障了数据的可靠传输。此外,HTTP/2 要求使用 TLS 协议进行加密通信,提高了数据的安全性。
-
兼容性: HTTP/2 通过与 HTTP/1.1 的兼容性保证,使得现有的 Web 应用可以逐渐迁移到 HTTP/2,而不需要进行大规模的更改。
HTTP/3------ 基于 QUIC 的 HTTP (2022)
HTTP 的下一个主要版本,HTTP/3 有这与 HTTP 早期版本的相同语义,但在传输层部分使用 QUIC (en-US) 而不是 TCP。到 2022 年 10 月,26% 的网站正在使用 HTTP/3。
QUIC 旨在为 HTTP 连接设计更低的延迟。类似于 HTTP/2,它是一个多路复用协议,但是 HTTP/2 通过单个 TCP 连接运行,所以在 TCP 层处理的数据包丢失检测和重传可以阻止所有流。QUIC 通过 UDP 运行多个流,并为每个流独立实现数据包丢失检测和重传,因此如果发生错误,只有该数据包中包含数据的流才会被阻止。
RFC 9114 定义的 HTTP/3 被 大多数主流浏览器所支持,包括 Chromium(及其他的变体,例如 Chrome 和 Edge)和 Firefox。
更多 HTTP3 的内容会随着发展逐步更新。
最后更新: 2024/3/16 上午 10:29
HTTP 协议之报文详解
老胡爱分享于 2014-04-20 12:51:28 发布
学习 WEB 开发需要对 HTTP 协议熟悉,下面直接进入主题。
一、报文
报文,是网络中交换和传输的数据单元,即站点一次性要发送的数据块。报文包含了将要发送的完整的数据信息,其长短很不一致,长度不限且可变。
HTTP 报文是由一行一行简单的字符串组成的。HTTP 报文都是纯文本,不是二进制代码,所以人们可以很方便地对其进行读写。如果说 HTTP 是因特网的信使,那么 HTTP 报文就是它用来搬东西的包裹了。
二、报文的流动
报文会流入源端服务器,工作完成之后,会流会用户的 Agent 代理。
HTTP 报文会像河水一样流动,不管是请求报文还是响应报文,所有报文都会向下游流动。所有报文的发送者都在接受者的上游。如下图所示,对请求报文来说,代理 1 位于代理 3 的上游,但对响应报文来说,它就位于代理 3 的下游。
三、报文的组成部分
HTTP 报文是简单的格式化文本。如下图所示。每条报文都包含一条来自客户端的请求或者一条来自服务器的响应。它们由三部分组成:对报文进行描述的起始行、包含属性的首部块以及可选的、包含数据的主体部分。
所有的 HTTP 报文都可以分为两类:请求报文和响应报文。请求报文会向 Web 服务器请求一个动作。响应报文会将请求的结果返回给客户端。请求报文和响应报文的基本报文结构相同。
1、报文的语法
请求报文的格式:
cobol
<method> <request-URL> <version>
<headers>
<entity-body>
响应报文的格式
cobol
<method> <status> <reason-phrase>
<headers>
<entity-body>
下面是对报文格式各部分的解释:
method (方法)
客户端希望服务器对资源执行的动作。是一个单独的词,如:GET、HEAD、POST。
request-URL (请求 URL)
命名了所请求资源,或者 URL 路径组件的完整 URL。
version (版本)
报文所使用的 HTTP 版本,其格式:HTTP/.
其中 major (主要版本号) 和 minor (次要版本号) 都是整数。
status (状态码)
由三位数字组成,描述了请求过程中所发生的情况。
reason-phrase (原因短语)
上面数字状态码的可读版本包含行终止序列之前的所有文本。
headers (首部)
可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号(:)
,然后是一个可选的空格,接着是一个值,最后是一个 CRLF。首部是由一个空行 (CRLF) 结束的,表示了首部列表的结束和实体主体部分的开始,
entity-body (实体的主体部分)
包含一个由任意数据组成的数据块。并不是所有的报文都包含实体的主体部分。有时,报文只是以一个 CRLF 结束。
2、起始行
所有的 HTTP 报文都以一个起始行作为开始。请求报文的起始行说明了要做些什么。响应报文的起始行说明发生了什么。
请求行。请求报文请求服务器对资源进行一些操作。请求报文的起始行,称为请求行,包含一个方法和一个请求 URL,方法描述了服务器应该执行的操作,请求 URL 描述了要对哪个资源执行这个方法。请求行还包含 HTTP 的版本,用来告知服务器,客户端使用的是哪种版本的 HTTP。所有的这些字段都由空格符分隔。在 HTTP/1.0 之前,并不要求请求行中包含 HTTP 版本号。
响应行。响应报文承载了状态信息和操作产生的所有结果数据,将其返回给客户端。响应报文的起始行,称为响应行,包含了响应报文使用的 HTTP 版本、数字状态码,以及描述状态码的文本信息的原因短语。所有的这些字段都由空格符分隔。在 HTTP/1.0 之前,并不要求响应行中包含 HTTP 版本号。
方法。请求的起始行以方法作为开始,方法用来告知服务器要做些什么。
HTTP 规范中定义了一组常用的请求方法。
注:并不是所有服务器都实现了上面列出的 7 种方法。而且,由于 HTTP 设计得易于扩展,所以除了这些方法以外,其他服务器可能还会是实现一些自己的请求方法,称为扩展方法。
状态码。用来告诉客户端,发生了什么事情。
客户端向一个 HTTP 服务器发送请求报文时,会发生很多事情。状态码是在每条响应报文的起始行中返回的。
下面是状态码的分类
原因短语。是响应起始行中最后一个组件。为状态码提供了文本形式的解释。例:200 OK 中,OK 就是原因短语。
版本号。为 HTTP 应用程序提供了一种将自己所遵循的协议版本告知对方的方式。版本号说明了应用程序支持的最高版本。版本好不会被当作小数来处理。版本的每个数字都回被当成一个单独的数字来处理。因此,每个数字都必须单独进行比较,以便确定哪个版本更高。比如,HTTP/2.22 就比 HTTP/2.3 的版本更高,因为 22 比 3 大。
3、首部
首部字段向请求和响应报文中添加一些附加信息。从本质上来说,它们只是一些名 / 值对的列表。
首部分类:
通用首部
既可以出现在请求报文中,也可以出现在响应报文中
请求首部
提供更多有关请求的信息
响应首部
提供更多有关响应的信息
实体首部
描述主体的长度和内容,或者资源自身
扩展首部
规范中没有定义的新首部
常见首部实例:
4、实体的主体部分
HTTP 报文的负荷。就是 HTTP 要传输的内容。
HTTP 报文可以承载很多类型的数字数据:图片、视频、HTML 文档、软件应用程序等。
参考文献:《HTTP 权威指南》
【Http】HTTP 报文结构及请求数据大小
志波同学 于 2015-09-10 16:35:26 发布
HTTP 报文结构如下:
HTTP 报文结构包含请求行、请求头、请求体三部分。一次请求示例如下图:
一、请求行【request-line】
POST 请求方法
/sso/login 请求 URL,及 URI
HTTP/1.1 HTTP 协议及版本
HTTP 协议没有限制请求行的长度。但是出于各种原因的考虑,各家的浏览器、服务器端都做了不同程度的限制。
1、浏览器限制
所有主流浏览器都会对 URI 的长度进行限制。如果你在浏览器中输入过长的 URI,那么浏览器会自动进行截断。各个浏览器对 URI 长度的限制各不相同,2000 字符以内的 URI 都能符合所有主流浏览器的要求。
2、服务端限制
一般服务是没有专门针对 URI 的参数限制的,但是由于 URI 是会包含在请求头中的,所以对请求头大小的限制是会影响 URI 的。
3、关于请求行的疑惑
HTTP 协议分为 request-line、request-header、request-body 三个部分的。在查看各浏览器、服务器配置的时候往往将 request-line、request-header 归为一类了,request-line 的数据大小受 request-header 的影响,比如 nginx 的 large_client_header_buffers 属性。
二、请求头【request-header】
请求头部存放了客户端请求的信息,包含 User-Agent、Accept、Host 等。请求头部由关键字 / 值对组成,每行一对,关键字和值用英文冒号 ":" 分隔。协议中也没有显示限制请求头的大小。但是出于各种原因的考虑,各家的浏览器、服务器端都做了不同程度的限制。
1、浏览器限制
各主流浏览器都限制请求头的大小,但值得大小不尽相同。
2、服务端限制
出于安全考虑,我们必须在服务器端对请求头大小进行限制,由于存放的信息比较简单,因此建议值不应超过 100K。
三、请求体【request-body】
HTTP 协议没有限制请求体的长度。HTTP 是支持文件传输的,文件的二进制数据不是放在请求行或者请求头里面,它是放在请求体里面的。
1、浏览器限制
如果浏览器对请求体大小做限制,可能会影响文件的传输,因此浏览器本身没有对请求体做大小限制。
2、服务端限制
出于安全考虑,我们必须在服务器端对请求体大小进行限制,请求体长度的最大值的设置有多方面的因素,需要根据业务情况反复调优决定。考虑以下几方面因素:
1、根据请求报文的大小,预估实际请求体的最大值;
2、限制上传文件的大小,文件上传服务与业务操作服务分离;
3、设置合理的超时时间,避免由于请求体太大导致线程被长时间占用;
4、请求体设置不能太大,防止轻易被 DDOS 攻击;
HTTP 响应报文
THE ORDER 于 2022-02-01 18:16:38 发布
1. HTTP 响应报文分析
HTTP 响应报文效果图:
响应报文说明:
--- 响应行 / 状态行 ---
HTTP/1.1 200 OK # HTTP 协议版本 状态码 状态描述
--- 响应头 ---
Server: Tengine # 服务器名称
Content-Type: text/html; charset=UTF-8 # 内容类型
Transfer-Encoding: chunked # 发送给客户端内容不确定内容长度,发送结束的标记是 0\r\n, Content-Length 表示服务端确定发送给客户端的内容大小,但是二者只能用其一。
Connection: keep-alive # 和客户端保持长连接
Date: Fri, 23 Nov 2018 02:01:05 GMT # 服务端的响应时间
--- 空行 ---
--- 响应体 ---
... # 响应给客户端的数据
原始响应报文说明:
HTTP/1.1 200 OK\r\n
Server: Tengine\r\n
Content-Type: text/html; charset=UTF-8\r\n
Transfer-Encoding: chunked\r\n
Connection: keep-alive\r\n
Date: Fri, 23 Nov 2018 02:01:05 GMT\r\n
\r\n (响应头信息后面还有一个单独的'\r\n'不能省略)
...
说明:
每项数据之间使用:\r\n
2. HTTP 状态码介绍
HTTP 状态码是用于表示 web 服务器响应状态的 3 位数字代码。
状态码 说明
200 请求成功
307 重定向
400 错误的请求,请求地址或者参数有误
404 请求资源在服务器不存在
500 服务器内部源代码出现错误
3. 小结
一个 HTTP 响应报文是由响应行、响应头、空行和响应体 4 个部分组成。 HTTP 响应报文
响应行是由三部分组成:HTTP 协议版本 状态码 状态描述,最常见的状态码是 200
HTTP 返回状态值详解
阳光岛主于 2013-09-07 06:49:39 发布
当用户点击或搜索引擎向网站服务器发出浏览请求时,服务器将返回 Http Header Http 头信息状态码。
常见几种如下:
1、Http/1.1 200 OK 访问正常
表示成功访问,为网站可正常访问时的状态。
2、Http/1.1 301 Moved Permanently 301 重定向 永久重定向
对搜索引擎相对友好的跳转方式,当网站更换域名时可将原域名作 301 永久重定向到新域名,原域名权重可传递到新域名,也常有将不含 www 的域名 301 跳转到含 www 的,如 xxx.com 通过 301 跳转到 www.xxx.com
3、Http/1.1 302 Found 为临时重定向
易被搜索引擎判为作弊,比如 asp 程序的 response.Redirect () 跳转、js 跳转或静态 http 跳转。
4、Http/1.1 400 Bad Request 域名绑定错误
一般是服务器上域名未绑定成功,未备案等情况。
5、Http/1.1 403 Forbidden 没有权限访问此站
你的 IP 被列入黑名单,连接的用户过多,可以过后再试,网站域名解析到了空间,但空间未绑定此域名等情况。
6、Http/1.1 404 Not Found 文件或目录不存在
表示请求文件、目录不存在或删除,设置 404 错误页时需确保返回值为 404。常有因为 404 错误页设置不当导致不存在的网页返回的不是 404 而导致搜索引擎降权。
7、Http/1.1 500 Internal Server Error 程序或服务器错误
表示服务器内部程序错误,出现这样的提示一般是程序页面中出现错误,如小的语法错误,数据连接故障等。
HTTP 状态码分类及含义
HTTP 状态码是用来表示 HTTP 请求的结果的,根据它们的含义,可以分为五类:
1xx(临时响应):请求收到,继续处理
2xx(成功):操作成功收到,分析、接受
3xx(重定向):完成此请求必须进一步处理
4xxx(请求错误):请求包含一个错误语法或不能完成
5xx(服务器错误):服务器执行一个完全有效请求失败
Http 状态码一览表
所谓的 404 页就是服务器 404 重定向状态返回页面。数字 404 指的是 404 号状态码。
一般常用到的有 200 号状态码和 404 号状态码。200 号表示网页被下载成功,而 404 号表示不能成功下载并产生错误。
下面是 HTTP 状态码一览表。
1xx:请求收到,继续处理
100------ 客户必须继续发出请求
101------ 客户要求服务器根据请求转换 HTTP 协议版本
2xx:操作成功收到,分析、接受
200------ 交易成功
201------ 提示知道新文件的 URL
202------ 接受和处理、但处理未完成
203------ 返回信息不确定或不完整
204------ 请求收到,但返回信息为空
205------ 服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206------ 服务器已经完成了部分用户的 GET 请求
3xx:完成此请求必须进一步处理
300------ 请求的资源可在多处得到
301------ 删除请求数据
302------ 在其他地址发现了请求数据
303------ 建议客户访问其他 URL 或访问方式
304------ 客户端已经执行了 GET,但文件未变化
305------ 请求的资源必须从服务器指定的地址得到
306------ 前一版本 HTTP 中使用的代码,现行版本中不再使用
307------ 申明请求的资源临时性删除
4xx:请求包含一个错误语法或不能完成
400------ 错误请求,如语法错误
401------ 请求授权失败
402------ 保留有效 ChargeTo 头响应
403------ 请求不允许
404------ 没有发现文件、查询或 URl
405------ 用户在 Request-Line 字段定义的方法不允许
406------ 根据用户发送的 Accept 拖,请求资源不可访问
407------ 类似 401,用户必须首先在代理服务器上得到授权
408------ 客户端没有在用户指定的饿时间内完成请求
409------ 对当前资源状态,请求不能完成
410------ 服务器上不再有此资源且无进一步的参考地址
411------ 服务器拒绝用户定义的 Content-Length 属性请求
412------ 一个或多个请求头字段在当前请求中错误
413------ 请求的资源大于服务器允许的大小
414------ 请求的资源 URL 长于服务器允许的长度
415------ 请求资源不支持请求项目格式
416------ 请求中包含 Range 请求头字段,在当前请求资源范围内没有 range 指示值,请求
也不包含 If-Range 请求头字段
417------ 服务器不满足请求 Expect 头字段指定的期望值,如果是代理服务器,可能是下
一级服务器不能满足请求
5xx:服务器执行一个完全有效请求失败
500------ 服务器产生内部错误
501------ 服务器不支持请求的[函数
502------ 服务器暂时不可用,有时是为了防止发生系统过载
503------ 服务器过载或暂停维修
504------ 关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505------ 服务器不支持或拒绝支请求头中指定的 HTTP 版本
=======================================================
一些常见的状态码为:
200 - 服务器成功返回网页
404 - 请求的网页不存在
503 - 服务器超时
下面提供 HTTP 状态码的完整列表。点击链接 可了解详情。您也可以访问 HTTP 状态码上的 W3C 页获取更多信息。
1xx (临时响应)
表示临时响应并需要请求者继续执行操作的状态码。
100 (继续) 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。
101 (切换协议) 请求者已要求服务器切换协议,服务器已确认并准备切换。
2xx (成功)
表示成功处理了请求的状态码。
200(成功) 服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。如果是对您的 robots.txt 文件显示此状态码,则表示 Googlebot 已成功检索到该文件。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。与 204 响应不同,此响应要求请求者重置文档视图 (例如,清除表单内容以输入新内容)。
206 (部分内容) 服务器成功处理了部分 GET 请求。
3xx (重定向)
要完成请求,需要进一步操作。通常,这些状态码用来重定向。Google 建议您在每次请求中使用重定向不要超过 5 次。您可以使用网站管理员工具查看一下 Googlebot 在抓取重定向网页时是否遇到问题。诊断下的网络抓取页列出了由于重定向错误导致 Googlebot 无法抓取的网址。
300 (多种选择) 针对请求,服务器可执行多种操作。服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。服务器返回此响应 (对 GET 或 HEAD 请求的响应) 时,会自动将请求者转到新位置。您应使用此代码告诉 Googlebot 某个网页或网站已永久移动到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似,会自动将请求者转到不同的位置,但您不应使用此代码来告诉 Googlebot 某个网页或网站已经移动,因为 Googlebot 会继续抓取原有位置并编制索引。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。对于除 HEAD 之外的所有请求,服务器会自动转到其他位置。
304 (未修改) 自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
如果网页自请求者上次请求后再也没有更改过,您应将服务器配置为返回此响应 (称为 If-Modified-Since HTTP 标头)。服务器可以告诉搜索引擎的蜘蛛 / 机器人 自从上次抓取后网页没有变更,进而节省带宽和开销。
305 (使用代理) 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。此代码与响应 GET 和 HEAD 请求的 301 代码类似,会自动将请求者转到不同的位置,但您不应使用此代码来告诉 Googlebot 某个页面或网站已经移动,因为 Googlebot 会继续抓取原有位置并编制索引。
4xx (请求错误)
这些状态码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。如果您在 Googlebot 尝试抓取您网站上的有效网页时看到此状态码 (您可以在 Google 网站管理员工具诊断下的网络抓取页面上看到此信息),可能是您的服务器或主机拒绝了 Googlebot 访问。
404 (未找到) 服务器找不到请求的网页。例如,对于服务器上不存在的网页经常会返回此代码。
如果您的网站上没有 robots.txt 文件,而您在 Google 网站管理员工具 "诊断" 标签的 robots.txt 页上看到此状态码,则这是正确的状态码。但是,如果您有 robots.txt 文件而又看到此状态码,则说明您的 robots.txt 文件可能命名错误或位于错误的位置 (该文件应当位于顶级域,名为 robots.txt)。
如果对于 Googlebot 抓取的网址看到此状态码 (在 "诊断" 标签的 HTTP 错误页面上),则表示 Googlebot 跟随的可能是另一个页面的无效链接 (是旧链接或输入有误的链接)。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态码与 401 (未授权) 类似,但指定请求者应当授权使用代理。如果服务器返回此响应,还表示请求者应当使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码,以及两个请求的差异列表。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。该代码与 404 (未找到) 代码类似,但在资源以前存在而现在不存在的情况下,有时会用来替代 404 代码。如果资源已永久移动,您应使用 301 指定资源的新位置。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI (通常为网址) 过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态码。
417 (未满足期望值) 服务器未满足 "期望" 请求标头字段的要求。
5xx (服务器错误)
这些状态码表示服务器在处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用 (由于超载或停机维护)。通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
via:
-
HTTP 的历史 | HTTP完全注释 wangjunliang 最后更新: 2024/3/16 上午10:29
https://junliangwangx.github.io/HTTP-Explanation/docs/overview/the-history-of-http.html -
HTTP 协议之报文详解_不发报文就可以接受所有报文 - CSDN 博客 老胡爱分享于 2014-04-20 12:51:28 发布
https://blog.csdn.net/yipiankongbai/article/details/24176693 -
【Http】HTTP 报文结构及请求数据大小_怎么确定请求体的大小 - CSDN 博客 志波同学 于 2015-09-10 16:35:26 发布
https://zhibo.blog.csdn.net/article/details/48342007 -
HTTP 响应报文 - CSDN 博客 THE ORDER 于 2022-02-01 18:16:38 发布
https://blog.csdn.net/weixin_44498127/article/details/122765290 -
HTTP 返回状态值详解 - CSDN 博客 阳光岛主于 2013-09-07 06:49:39 发布
https://blog.csdn.net/ithomer/article/details/10240351 -
论 HTTP 请求大小 - 轩脉刃 - 博客园 2013-03-29 09:55 轩脉刃
https://www.cnblogs.com/yjf512/archive/2013/03/29/2988296.html