HTTP 基础



参考博客:https://blog.youkuaiyun.com/qq_36894974/article/details/103930478


1、认识 HTTP

HTTPHyperText Transfer Protocol超文本传输协议)协议定义了浏览器如何向万维网服务器请求万维网文档,以及服务器如何把文档传送给浏览器

HTTP面向事务的(Transaction oriented)应用层协议,它是万维网上能够可靠地交换文件(包括文本超文本声音图像等各种多媒体文件)的重要基础。

超文本传输协议 可以进行文字分割:超文本(Hypertext)、传输(Transfer)、协议(Protocol),它们之间的关系如下:
在这里插入图片描述

1.1 超文本

在互联网早期的时候,我们输入的信息只能保存在本地,无法和其他电脑进行交互。我们保存的信息通常都以文本即简单字符的形式存在,文本是一种能够被计算机解析的有意义的二进制数据包。而随着互联网的高速发展,两台电脑之间能够进行数据的传输后,人们不满足只能在两台电脑之间传输文字,还想要传输图片、音频、视频,甚至点击文字或图片能够进行 超链接 的跳转,那么文本的语义就被扩大了,这种语义扩大后的文本就被称为超文本(Hypertext)

2、与 HTTP 有关的组件


2.1 Web 服务器

Web 服务器的正式名称叫做 Web Server,Web 服务器 一般指的是 网站服务器,上面说到浏览器是 HTTP 请求的发起方,那么 Web 服务器 就是 HTTP 请求的应答方,Web 服务器 可以向 浏览器 等 Web 客户端 提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。

3、与 HTTP 有关的协议


3.1 TCP/IP

TCP 协议的全称是 Transmission Control Protocol 的缩写,意思是 传输控制协议。HTTP 使用 TCP 作为通信协议,这是因为 TCP 是一种可靠的协议,而可靠能保证数据不丢失。

IP 协议的全称是 Internet Protocol 的缩写,它主要解决的是通信双方寻址的问题。

3.2 DNS

计算机网络中的每个端系统都有一个 IP 地址存在,而把 IP 地址转换为便于人类记忆的协议就是 DNS 协议。

DNS 的全称是 域名系统(Domain Name System,缩写:DNS),它作为将域名和 IP 地址相互映射的一个 分布式数据库,能够使人更方便地访问互联网。

3.3 URI / URL

URI的全称是(Uniform Resource Identifier),中文名称是统一资源标识符,使用它就能够唯一地标记互联网上资源。

URL的全称是(Uniform Resource Locator),中文名称是统一资源定位符,也就是我们俗称的网址,它实际上是 URI 的一个子集。

URI 不仅包括 URL,还包括 URN(统一资源名称),它们之间的关系如下:
在这里插入图片描述

3.4 HTTPS

HTTP 一般是 明文传输,很容易被攻击者窃取重要信息,鉴于此,HTTPS 应运而生。HTTPS 的全称为 (Hyper Text Transfer Protocol over SecureSocket Layer),全称有点长,HTTPS 和 HTTP 有很大的不同在于 HTTPS 是以安全为目标的 HTTP 通道,在 HTTP 的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在 HTTP 的基础上增加了 SSL 层,也就是说 HTTPS = HTTP + SSL。


4、HTTP 请求响应过程

们通过一个例子来探讨一下,我们假设访问的 URL 地址为 http://www.someSchool.edu/someDepartment/home.index,当我们输入网址并点击回车时,浏览器内部会进行如下操作:

  1. DNS服务器会首先进行域名的映射,找到访问www.someSchool.edu所在的地址,然后HTTP 客户端进程在 80 端口发起一个到服务器 www.someSchool.edu 的 TCP 连接(80 端口是 HTTP 的默认端口)。在客户和服务器进程中都会有一个套接字与其相连。
  2. HTTP 客户端通过它的套接字向服务器发送一个 HTTP 请求报文。该报文中包含了路径 someDepartment/home.index 的资源,我们后面会详细讨论 HTTP 请求报文。
  3. HTTP 服务器通过它的套接字接受该报文,进行请求的解析工作,并从其存储器(RAM 或磁盘)中检索出对象 www.someSchool.edu/someDepartment/home.index,然后把检索出来的对象进行封装,封装到 HTTP 响应报文中,并通过套接字向客户进行发送。
  4. HTTP 服务器随即通知 TCP 断开 TCP 连接,实际上是需要等到客户接受完响应报文后才会断开 TCP 连接。
  5. HTTP 客户端接受完响应报文后,TCP 连接会关闭。HTTP 客户端从响应中提取出报文中是一个 HTML 响应文件,并检查该 HTML 文件,然后循环检查报文中其他内部对象。
  6. 检查完成后,HTTP 客户端会把对应的资源通过显示器呈现给用户。

至此,键入网址再按下回车的全过程就结束了。上述过程描述的是一种简单的请求-响应全过程,真实的请求-响应情况可能要比上面描述的过程复杂很多。

5、HTTP 请求特征

从上面整个过程中我们可以总结出 HTTP 进行分组传输是具有以下特征:

  1. 支持客户-服务器模式
  2. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
  3. 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。
  4. 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  5. 无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

6、详解 HTTP 报文

HTTP 报文的组成格式。

HTTP 协议主要由三大部分组成:

序号组成部分描述
1起始行(start line)描述请求或响应的基本信息
2头部字段(header)使用 key-value 形式更详细地说明报文
3消息正文(entity)实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据

其中起始行和头部字段并成为 请求头 或者 响应头,统称为 Header;消息正文也叫做实体,称为 body。HTTP 协议规定每次发送的报文必须要有 Header,但是可以没有 body,也就是说头信息是必须的,实体信息可以没有。而且在 header 和 body 之间必须要有一个空行(CRLF),如果用一幅图来表示一下的话,应该是下面这样:
在这里插入图片描述
使用上面的那个例子来看一下 http 的请求报文:
在这里插入图片描述
如图,这是 http://www.someSchool.edu/someDepartment/home.index 请求的请求头,通过观察这个 HTTP 报文我们就能够学到很多东西,首先,我们看到报文是用普通 ASCII 文本书写的,这样保证人能够可以看懂。然后,我们可以看到每一行和下一行之间都会有换行,而且最后一行(请求头部后)再加上一个回车换行符。

每个报文的起始行都是由三个字段组成:方法、URL 字段和 HTTP 版本字段。
在这里插入图片描述

6.1 HTTP 请求 方法

HTTP 请求方法一般分为 8 种,一般最常用的方法也就是 GET 方法和 POST 方法:

  1. GET 获取资源,GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;

  2. POST 传输实体,虽然 GET 方法也可以传输主体信息,但是便于区分,我们一般不用 GET 传输实体信息,反而使用 POST 传输实体信息。

我们一般最常用的方法也就是 GET 方法和 POST 方法,其他方法暂时了解即可。

6.2 HTTP 请求 URL

HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。URL 带有请求对象的标识符。在上面的例子中,浏览器正在请求对象 /somedir/page.html 的资源。

通过一个完整的域名解析一下 URL:
比如 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument 这个 URL 比较繁琐了吧,你把这个 URL 搞懂了其他的 URL 也就不成问题了。

6.2.1 http

首先出场的是 http
在这里插入图片描述
http:// 告诉浏览器使用何种协议。对于大部分 Web 资源,通常使用 HTTP 协议或其安全版本,HTTPS 协议。另外,浏览器也知道如何处理其他协议。例如, mailto: 协议指示浏览器打开邮件客户端;ftp:协议指示浏览器处理文件传输。

6.2.2 主机

第二个出场的是 主机
在这里插入图片描述
www.example.com 既是一个域名,也代表管理该域名的机构。它指示了需要向网络上的哪一台主机发起请求。当然,也可以直接向主机的 IP address 地址发起请求。但直接使用 IP 地址的场景并不常见。

6.2.3 端口

第三个出场的是 端口
在这里插入图片描述
前面说到,两个主机之间要发起 TCP 连接需要两个条件,主机 + 端口。它表示用于访问 Web 服务器上资源的入口。如果访问的该 Web 服务器使用HTTP协议的标准端口(HTTP为80,HTTPS为443)授予对其资源的访问权限,则通常省略此部分。否则端口就是 URI 必须的部分。

上面是请求 URL 所必须包含的部分,下面就是 URL 具体请求资源路径。

6.2.4 路径

第四个出场的是 路径
在这里插入图片描述
/path/to/myfile.html 是 Web 服务器上资源的路径。以端口后面的第一个 / 开始,到 ? 号之前结束,中间的 每一个 / 都代表了层级(上下级)关系。这个 URL 的请求资源是一个 html 页面。

6.2.5 查询参数

紧跟着路径后面的是 查询参数
在这里插入图片描述
?key1=value1&key2=value2 是提供给 Web 服务器的额外参数。如果是 GET 请求,一般带有请求 URL 参数,如果是 POST 请求,则不会在路径后面直接加参数。这些参数是用 & 符号分隔的键/值对列表。key1 = value1 是第一对,key2 = value2 是第二对参数。

6.2.6 锚点

紧跟着参数的是 锚点
在这里插入图片描述
#SomewhereInTheDocument 是资源本身的某一部分的一个锚点。锚点代表资源内的一种“书签”,它给予浏览器显示位于该“加书签”点的内容的指示。 例如,在HTML文档上,浏览器将滚动到定义锚点的那个点上;在视频或音频文档上,浏览器将转到锚点代表的那个时间。值得注意的是 # 号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。


6.3 HTTP 版本

表示报文使用的 HTTP 协议版本。


6.4 请求头部

在表述完了起始行之后我们再来看一下请求头部,现在我们向上找,找到http://www.someSchool.edu/someDepartment/home.index,来看一下它的请求头部:

Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr

这个请求头信息比较少,首先 Host 表示的是对象所在的主机。你也许认为这个 Host 是不需要的,因为 URL 不是已经指明了请求对象的路径了吗?这个首部行提供的信息是 Web 代理高速缓存 所需要的。Connection: close 表示的是浏览器需要告诉服务器使用的是 非持久连接。它要求服务器在发送完响应的对象后就关闭连接。User-agent: 这是请求头用来告诉 Web 服务器,浏览器使用的类型是 Mozilla/5.0,即 Firefox 浏览器。Accept-language 告诉 Web 服务器,浏览器想要得到对象的法语版本,前提是服务器需要支持法语类型,否则将会发送服务器的默认版本。下面我们针对主要的实体字段进行介绍(具体的可以参考 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers MDN 官网学习)

HTTP 的请求标头分为四种: 通用标头实体标头请求标头响应标头 ,依次来进行详解。

6.4.1 通用标头

通用标头主要有三个,分别是 DateCache-ControlConnection

6.4.1.1 Date

Date 是一个通用标头,它可以出现在请求标头和响应标头中,它的基本表示如下:

Date: Wed, 21 Oct 2015 07:28:00 GMT 

表示的是格林威治标准时间,这个时间要比北京时间慢八个小时
在这里插入图片描述

6.4.1.2 Cache-Control

Cache-Control 是一个通用标头,他可以出现在请求标头和响应标头中,Cache-Control 的种类比较多,虽然说这是一个通用标头,但是又一些特性是请求标头具有的,有一些是响应标头才有的。主要大类有 可缓存性阈值性重新验证并重新加载其他特性

可缓存性是唯一响应标头才具有的特性,我们会在响应标头中详述。

阈值性,这个我翻译可能不准确,它的原英文是 Expiration,我是根据它的值来翻译的,你看到这些值可能会觉得我翻译的有点道理

  1. max-age: 资源被认为仍然有效的最长时间,与 Expires 不同,这个请求是相对于 request标头的时间,而 Expires 是相对于响应标头。(请求标头)
  2. s-maxage: 重写了 max-age 和 Expires 请求头,仅仅适用于共享缓存,被私有缓存所忽略(这块不理解,看完响应头的 Cache-Control 再进行理解)(请求标头)
  3. max-stale:表示客户端将接受的最大响应时间,以秒为单位。(响应标头)
  4. min-fresh: 表示客户端希望响应在指定的最小时间内有效。(响应标头)

6.4.1.3 Connection

Connection 决定当前事务(一次三次握手和四次挥手)完成后,是否会关闭网络连接。Connection 有两种,一种是 持久性连接,即一次事务完成后不关闭网络连接

Connection: keep-alive

另一种是 非持久性连接,即一次事务完成后关闭网络连接

Connection: close

HTTP1.1 其他通用标头如下:
在这里插入图片描述

6.4.2 实体标头

实体标头是描述消息正文内容的 HTTP 标头。实体标头用于 HTTP 请求和响应中。头部 Content-LengthContent-LanguageContent-Encoding 是实体头。

  1. Content-Length 实体报头指示实体主体的大小,以字节为单位,发送到接收方。
  2. Content-Language 实体报头描述了客户端或者服务端能够接受的语言,例如
Content-Language: de-DE
Content-Language: en-US
Content-Language: de-DE, en-CA
  1. Content-Encoding 这又是一个比较麻烦的属性,这个实体报头用来压缩媒体类型。Content-Encoding 指示对实体应用了何种编码。
    常见的内容编码有这几种: gzip、compress、deflate、identity ,这个属性可以应用在请求报文和响应报文中
Accept-Encoding: gzip, deflate //请求头
Content-Encoding: gzip  //响应头

下面是一些实体标头字段:
在这里插入图片描述

6.4.3 请求标头

上面给出的例子请求报文的属性比较少,下面给出一个 MDN 官网的例子:

GET /home.html 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/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0 

6.4.3.1 Host

Host 请求头指明了服务器的域名(对于虚拟主机来说),以及(可选的)服务器监听的TCP端口号。如果没有给定端口号,会自动使用被请求服务的默认端口(比如请求一个 HTTP 的 URL 会自动使用80作为端口)。

Host: developer.mozilla.org

上面的 AccpetAccept-LanguageAccept-Encoding 都是属于内容协商的请求标头,我们会在下面说明。

6.4.3.2 Referer

HTTP Referer 属性是请求标头的一部分,当浏览器向 web 服务器发送请求的时候,一般会带上 Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。

Referer: https://developer.mozilla.org/testpage.html

6.4.3.3 Upgrade-Insecure-Requests

Upgrade-Insecure-Requests 是一个请求标头,用来向服务器端发送信号,表示客户端优先选择加密及带有身份验证的响应。

Upgrade-Insecure-Requests: 1

6.4.3.4 If-Modified-Since

HTTP 的 If-Modified-Since 使其成为条件请求

  1. 返回200,只有在给定日期的最后一次修改资源后,服务器才会以200状态发送回请求的资源。
  2. 如果请求从开始以来没有被修改过,响应会返回304并且没有任何响应体

If-Modified-Since 通常会与 If-None-Match 搭配使用,If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确定。

大白话说就是如果在 Last-Modified 之后更新了服务器资源,那么服务器会响应200,如果在 Last-Modified 之后没有更新过资源,则返回 304。

If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT

6.4.3.5 If-None-Match

If-None-Match HTTP请求标头使请求成为条件请求。 对于 GET 和 HEAD 方法,仅当服务器没有与给定资源匹配的 ETag 时,服务器才会以200状态发送回请求的资源。 对于其他方法,仅当最终现有资源的 ETag 与列出的任何值都不匹配时,才会处理请求。

If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"

ETag 属于响应标头,后面进行介绍。

6.4.3.6 内容协商

内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的标准。
在这里插入图片描述
内容协商主要有以下3种类型:

(1)服务器驱动协商(Server-driven Negotiation)
这种协商方式是由服务器端进行内容协商。服务器端会根据请求首部字段进行自动处理。

(2)客户端驱动协商(Agent-driven Negotiation)
这种协商方式是由客户端来进行内容协商。

(3)透明协商(Transparent Negotiation)
是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。

内容协商的分类有很多种,主要的几种类型是 Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Language。

6.4.4 响应标头

响应标头是可以在 HTTP 响应种使用的 HTTP 标头,这听起来是像一句废话,不过确实是这样解释。并不是所有出现在响应中的标头都是响应标头。还有一些特殊的我们上面说过,有通用标头和实体标头也会出现在响应标头中,比如 Content-Length 就是一个实体标头,但是,在这种情况下,这些实体请求通常称为响应头。下面以一个例子为例和你探讨一下响应头。

200 OK
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a"
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
x-frame-options: DENY

6.4.4.1 响应状态码

首先出现的应该就是 200 OK,这是 HTTP 响应标头的状态码,它表示着响应成功完成。HTTP 响应标头的状态码有很多,并做了如下规定:

2xx 为开头的都表示请求成功响应:

状态码含义
200成功响应
204请求处理成功,但是没有资源可以返回
206对资源某一部分进行响应,由Content-Range 指定范围的实体内容。

3xx 为开头的都表示需要进行附加操作以完成请求:

状态码含义
301永久性重定向,该状态码表示请求的资源已经重新分配 URI,以后应该使用资源现有的 URI
302临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问
303该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源
304该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况
307临时重定向。该状态码与 302 Found 有着相同的含义

4xx 的响应结果表明客户端是发生错误的原因所在:

状态码含义
400该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
401该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息
403该状态码表明对请求资源的访问被服务器拒绝了
404该状态码表明服务器上无法找到请求的资源

5xx 为开头的响应标头都表示服务器本身发生错误:

状态码含义
500该状态码表明服务器端在执行请求时发生了错误
503该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

6.4.4.2 Access-Control-Allow-Origin

一个返回的 HTTP 标头可能会具有 Access-Control-Allow-Origin ,Access-Control-Allow-Origin 指定一个来源,它告诉浏览器允许该来源进行资源访问。 否则-对于没有凭据的请求 *通配符,告诉浏览器允许任何源访问资源。例如,要允许源 https://mozilla.org 的代码访问资源,可以指定:

Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin

如果服务器指定单个来源而不是 * 通配符的话 ,则服务器还应在 Vary 响应标头中包含 Origin ,以向客户端指示 服务器响应将根据原始请求标头的值而有所不同。

6.4.4.3 Keep-Alive

上面我们提到,HTTP 报文标头会分为四种,这其实是按着上下文来分类的。

还有一种分类是根据代理进行分类,根据代理会分为 端到端头逐跳标头

而 Keep-Alive 表示的是 Connection 非持续连接的存活时间,如下

Connection: Keep-Alive
Keep-Alive: timeout=5, max=997

Keep-Alive 有两个参数,它们是以逗号分隔的参数列表,每个参数由一个标识符和一个由等号 = 分隔的值组成。

timeout:指示空闲连接必须保持打开状态的最短时间(以秒为单位)。

max:指示在关闭连接之前可以在此连接上发送的最大请求数。

上述 HTTP 代码的意思就是限制最大的超时时间是 5s 和 最大的连接请求是 997 个。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值