HTTP 协议的前世今生

£可爱£侵袭症+ 提交于 2021-02-19 12:06:28
你知道当我们在网页浏览器的地址栏中输入 URL 时,Web 页面是如何呈现的吗?

🎓 尽人事,听天命。博主东南大学研究生在读,热爱健身和篮球,正在为两年后的秋招准备中,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步

🎁 本文已收录于 CS-Wiki(Gitee 官方推荐项目,现已 0.9k star),致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习

 

0. 前言

你知道当我们在网页浏览器的地址栏中输入 URL 时,Web 页面是如何呈现的吗?

Web 界面当然不会凭空出来,根据 Web 浏览器地址栏中指定的 URL,Web 使用一种名为 HTTP 的协议作为规范,完成从客户端到服务端的一些流程。可以说,Web 是建立在 HTTP 协议上进行通信的

1. HTTP 的诞生

其实,在 1983 年 3 月之前,互联网还只属于少数人,全世界的网民之间的信息是无法共享的。在这一互联网的黎明时期,HTTP 应运而生。

欧洲核子研究组织的 Tim Berners-Lee 博士提出了一种能够让远隔两地的网民共享知识的设想,最初的理念是:借助多文档之间相互关联的超文本(HyperTest),连成可相互参阅的 WWW(World Wide Web,万维网)。

现在已提出了 3 项 WWW 构建技术,分别是:

  • 把 SGML(标准通用标记语言)作为页面的文本标记语言 HTML

  • 作为文档传递协议的 HTTP

  • 指定文档所在地址的 URL

WWW 这一名称,是 Web 浏览器当年用来浏览超文本的客户端应用程序的名称,现在用来表示这一系列的集合,也可简称为 Web。

2. 什么是 HTTP

说了这么多,大家只知道 HTTP 很牛逼,对 HTTP 是什么仍然没有很直观的概念。别急,在了解什么是 HTTP 之前,我们有必要知道超文本是什么。

HTTP 传输的内容就是超文本

  • 我们先来理解「文本」:在互联网早期的时候只是简单的字符文字,但随着技术的发展,现在「文本」的涵义已经可以扩展为图片、视频、压缩包等,在 HTTP 眼里这些都算做「文本」。

  • 再来理解「超文本」:它就是超越了普通文本的文本,它是文字、图片、视频等的混合体。最关键有超链接,能从一个超文本跳转到另外一个超文本。

    HTML 就是最常见的超文本了,它本身只是纯文字文件,但内部用很多标签定义了图片、视频等的链接,在经过浏览器的解析,呈现给我们的就是一个文字、有画面的网页了。

OK,下面我们正式介绍什么是 HTTP?

HTTP:超文本传输协议(HyperText Transfer Protocol)是当今互联网上应用最为广泛的一种网络协议。所有的 WWW(万维网) 文件都必须遵守这个标准。HTTP 和 TCP/IP 协议簇中的众多协议一样,用于客户端和服务器端之间的通信。

3. 驻足不前的 HTTP

至今被世人广泛使用的 HTTP 协议,仍然是 20 多年前的版本。也就是说,作为 Web 文档传输协议的 HTTP,它的版本几乎没有更新,从另一方面来说,前人的智慧真的牛逼 👍

HTTP/0.9:HTTP 于 1990 年问世,功能简陋,仅支持 GET 请求方式,并且仅能访问 HTML 格式的资源。那时的 HTTP 并没有作为正式的标准被建立,因此被被称为 HTTP 0.9。

HTTP/1.0:1996 年 5 月 HTTP 正式作为标准被公布,版本号为 HTTP 1.0。在 0.9 版本上做了进步,增加了请求方式 POST 和 HEAD;不再局限于 0.9 版本的 HTML 格式,根据 Content-Type 可以支持多种数据格式...... 需要注意的是:1.0 版本的工作方式是短连接。虽说 HTTP/1.0 是初期标准,但该协议标准至今仍然在被广泛使用。

HTTP/1.1:1997 年公布的 HTTP 1.1 是目前主流的 HTTP 协议版本。当年的 HTTP 协议的出现主要是为了解决文本传输的难题,现在的 HTTP 早已超出了 Web 这个框架的局限,被运用到了各种场景里。当然,1.1 版本的最大变化,就是引入了长连接以及流水线机制(管道机制)。

这里面出现的各种专有名词大家留个印象就行,下文会逐渐讲解。

4. 区分 URL 和 URI

与 URI(统一资源标识符) 相比,大家应该更熟悉 URL(Uniform Resource Location,统一资源定位符),URL 就是我们使用 Web 浏览器访问 Web 页面时需要输入的网页地址。比如

URI 是 Uniform Resource Identifier 的缩写,RFC 2386 分别对这三个单词进行如下定义:

  • Uniform:统一规定的格式可方便处理多种不同类型的资源

  • Resource:资源的定义是可标识的任何东西。不仅可以是单一的,也可以是一个集合

  • Identifier:标识可标识的对象。也称为标识符

综上,URI 就是由某个协议方法表示的资源的定位标识符。比如说,采用 HTTP 协议时,协议方案就是 http,除此之外,还有 ftptelnet 等,标准的 URI 协议方法有 30 种左右。

URI 有两种格式,相对 URI 和绝对 URI。

  • 相对 URI:指从浏览器中基本 URI 处指定的 URL,形如 /user/logo.png

  • 绝对 URI:使用涵盖全部必要信息

总结来说:URI 用字符串标识某一处互联网资源,而 URL 标识资源的地点(互联网上所处的位置),可见 URL 是 URI 的子集

5. HTTP 请求和响应

HTTP 协议规定,在两台计算机之间使用 HTTP 协议进行通信时,在一条通信线路上必定有一端是客户端,另一端则是服务端。当在浏览器中输入网址访问某个网站时, 你的浏览器(客户端)会将你的请求封装成一个 HTTP 请求发送给服务器站点,服务器接收到请求后会组织响应数据封装成一个 HTTP 响应返回给浏览器。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

下面我们详细分析一下 HTTP 的请求报文和响应报文

① HTTP 请求报文

HTTP 请求报文由 3 大部分组成:

1)请求行(必须在 HTTP 请求报文的第一行)

2)请求头(从第二行开始,到第一个空行结束。请求头和请求体之间存在一个空行)

3)请求体(通常以键值对 {key:value}方式传递数据)

举个请求报文的例子:

请求行开头的 POST 表示请求访问服务器的类型,称为方法(method)。随后的字符串 /form/login 指明了请求访问的资源对象,也叫做请求 URI(request-URI)。最后的 HTTP/1.1 即 HTTP 的版本号,用来提示客户端使用的 HTTP 协议功能。

综上来看,这段请求的意思就是:请求访问某台 HTTP 服务器上的 /form/login 页面资源,并附带参数 name = veal、age = 37。

注意,无论是 HTTP 请求报文还是 HTTP 响应报文,请求头/响应头和请求体/响应体之间都会有一个空行,且请求体/响应体并不是必须的。

HTTP 请求方法

请求行中的方法的作用在于可以指定请求的资源按照期望产生某种行为,即使用方法给服务器下命令

包括(HTTP 1.1):GETPOSTPUTHEADDELETEOPTIONSCONNECTTRACE。当然,我们在开发中最常见也最常使用的就只有前面三个。

1)GET 获取资源

GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容

使用 GET 方法请求-响应的例子:

2)POST 传输实体主体

POST 主要用来传输数据,而 GET 主要用来获取资源。

使用 POST 方法请求-响应的例子:

3)PUT 传输文件

PUT 方法用来传输文件,由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。

使用 PUT 方法请求-响应的例子:

4)HEAD 获取报文首部

和 GET 方法类似,但是不返回报文实体主体部分。主要用于确认 URI 的有效性以及资源更新的日期时间等。

使用 HEAD 方法请求-响应的例子:

5)DELETE 删除文件

与 PUT 功能相反,用来删除文件,并且同样不带验证机制,按照请求 URI 删除指定的资源。

使用 DEELTE 方法请求-响应的例子:

6)OPTIONS 查询支持的方法

用于获取当前 URI 所支持的方法。若请求成功,会在 HTTP 响应头中包含一个名为 “Allow” 的字段,值是所支持的方法,如 “GET, POST”。

使用 OPTIONS 方法请求-响应的例子:

7)..........

HTTP 请求头

请求头用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。以下列出常见请求头:

1)Referer:表示这个请求是从哪个 URI 跳过来的。比如说通过百度来搜索淘宝网,那么在进入淘宝网的请求报文中,Referer 的值就是:www.baidu.com。如果是直接访问就不会有这个头。这个字段通常用于防盗链。

2)Accept:告诉服务端,该请求所能支持的响应数据类型。(对应的,HTTP 响应报文中也有这样一个类似的字段 Content-Type,用于表示服务端发送的数据类型,如果 Accept 指定的类型和服务端返回的类型不一致,就会报错)

上图中的 text/plain;q = 0.3 表示对于 text/plain 媒体类型的数据优先级/权重为 0.3(q 的范围 0 ~ 1)。不指定权重的,默认为 1.0。

数据格式类型如下图:

3)Host:告知服务器请求的资源所处的互联网主机名和端口号。该字段是 HTTP/1.1 规范中唯一一个必须被 包含在请求头中的字段。

4)Cookie:客户端的 Cookie 就是通过这个报文头属性传给服务端的!

Cookie: JSESSIONID=15982C27F7507C7FDAF0F97161F634B5

5)Connection:表示客户端与服务连接类型;Keep-Alive 表示持久连接,close 已关闭

6)Content-Length:请求体的长度

7)Accept-Language:浏览器通知服务器,浏览器支持的语言

8)Range:对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围

9)......

② HTTP响应报文

HTTP的响应报文也由三部分组成:

  • 响应行(必须在 HTTP 响应报文的第一行)

  • 响应头(从第二行开始,到第一个空行结束。响应头和响应体之间存在一个空行)

  • 响应体

在响应行开头的 HTTP 1.1 表示服务器对应的 HTTP 版本。紧随的 200 OK 表示请求的处理结果的状态码原因短语

HTTP 状态码

HTTP 状态码负责表示客户端 HTTP 请求的的返回结果、标记服务器端处理是否正常、通知出现的错误等工作。(重中之重!!!,和我们日常开发息息相关)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!