一、URI 和 URL
与 URI(统一资源标识符)相比,我们更熟悉 URL(统一资源定位符)。URl 正式使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。比如:http://zyxwmj.top 就是 URL。
URI 就是由某个协议方案表示的资源的定位标识符,协议方案是指访问资源所使用的协议类型名称。采用 http 协议时,协议方案就是 http。除此之外,还有 ftp、mailto、telnet、file 等。URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位置)。可见 URL 是 URI 的子集。
1、URI 格式
表示指定的 URI,要使用涵盖全部必要信息的绝对 URI、绝对 URL 以及相对 URL。相对 URL,是指从浏览器中基本 URI 处指定的 URL,形如 /image/logo.gif。
- 协议方案名:使用 http: 或 https: 等协议方案名获取访问资源时要指定协议类型。不区分字母大小写,最后附一个冒号(:)。也可使用 data: 或 javascript: 这类指定数据或脚本程序的方案名。
- 登录信息(认证):指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
- 服务器地址:使用绝对 URI 必须指定待访问的服务器地址。地址可以是类似 zyxwmj.top 这种 DNS 可解析的名称,或是 192.168.1.1 这类 IPv4 地址名,还可以是 [0:0:0:0:0:0:0:1] 这样用方括号括起来的 IPv6 地址名。
- 服务器端口号:指定服务器连接的网络端口号。此项也是可选项,若用户省略则自动使用默认端口号。
- 带层次的文件路径:指定服务器上的文件路径来定位特指的资源。这与 UNIX 系统的文件目录结构相似。
- 查询字符串:针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。此项可选。
- 片段标识符:使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置)。但在 RFC 中并没有明确规定其使用方法。该项也为可选项。
2、同源策略
同源策略是浏览器对 Javascript 进行跨域访问的安全策略,同时也是浏览器沙盒环境提供的一项制约。
URL 格式中,协议,主机,端口三部分相同才能算是同源。浏览器设置里,默认情况下只有同源的内容才能相互操作(js访问)。
(1)跨域资源共享(CORS)
跨域资源共享 CORS,解决 JS 跨域访问的问题,即 A 网站引用 B 网站内容。CORS 标准新增了一组 HTTP 头部字段,允许服务器声明哪些源站通过浏览器访问哪些资源。
// * 号代表所有的网站
Access-Control-Allow-Orgin:*
(2)内容安全策略(CSP)
A 网站应用 B 网站内容,A 网站所在浏览器,让不让用 B 网站内容。
Content-Security-Policy:
二、HTTP/1.1
HTTP 超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于 TCP/IP 协议传输数据,互联网上应用最为广泛的一种网络协议,所有的 WWW 文件都必须遵守这个标准。设计 HTTP 的初衷是为了提供一种发布和接收 HTML 页面的方法。
1、HTTP 的历史
| 版本 | 产生时间 | 内容 | 发展现状 |
| :-: | :-: | - | - |
| HTTP/0.9 | 1991年 | 不涉及数据包传输,规定客户端和服务器之间通信格式,只能 GET 请求 | 没有作为正式的标准 |
| HTTP/1.0 | 1996年 | 传输内容格式不限制,增加 PUT、PATCH、HEAD、OPTIONS、DELETE 命令 | 正式作为标准 |
| HTTP/1.1 | 1997年 | 持久连接(长连接)、节约带宽、HOST 域、管道机制、分块传输编码 | 2015 年前使用最广泛 |
| HTTP/2 | 2015年 | 多路复用、服务器推送、头信息压缩、二进制协议等。 | 逐渐覆盖市场 |
多路复用:通过单一的 HTTP/2 连接请求发送多重的请求、响应消息、多个请求 stream 共享一个 TCP 连接,实现多留并行而不是依赖建立多个 TCP 连接。
2、HTTP 是无状态的协议
http 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说在 http 这个级别,协议对于发送过的请求或响应都不做持久化处理。
随着 Web 的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。
- 通过Cookie/Session技术;
- HTTP/1.1持久连接(HTTP keep-alive)方法,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态,在请求首部字段中的 Connection: keep-alive 即为表明使用了持久连接。
3、请求方法
HTTP/1.0 和 HTTP/1.1 支持的方法:
(1)GET
GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器 端解析后返回响应内容。请求和响应的例子:
(2)POST
POST 方法用来传输实体的主体。虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行传输,而是用 POST 方法。虽说 POST 的功能与 GET 很相似,但 POST 的主要目的并不是获取响应的主体内容。请求和响应的例子:
(3)PUT
PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。但是,鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制,任何人都可以上传文件 , 存在安全性问题,因此一般的 Web 网站不使用该方法。若配合 Web 应用程序的验证机制,或架构设计采用 REST(REpresentational State Transfer,表征状态转移)标准的同类 Web 网站,就可能会开放使用 PUT 方法。(响应的意思其实是请求执行成功了,但无数据返回)
(4)HEAD
HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。
(5)DELETE
DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按 请求 URI 删除指定的资源。但是,HTTP/1.1 的 DELETE 方法本身和 PUT 方法一样不带验证机制,所以一般的 Web 网站也不使用 DELETE 方法。当配合 Web 应用程序的验证机制,或遵守 REST 标准时还是有可能会开放使用的。
(6)OPTIONS
OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。
(7)TRACE
TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。
客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修改/篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE 方法就是用来确认连接过程中发生的一系列操作。 但是,TRACE 方法本来就不怎么常用,再加上它容易引发 XST(Cross-Site Tracing,跨站追踪)攻击,通常就更不会用到了。
(8)CONNECT
CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。CONNECT 方法的格式如:CONNECT 代理服务器名:端口号 HTTP版本
。
4、持久连接节省通信量
HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接。比如:使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。
(1)持久连接
为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。(建立 1 次 TCP 连接后进行多次请求和响应的交互)
在 HTTP/1.1 中,所有的连接默认都是持久连接,但在 HTTP/1.0 内并未标准化。虽然有一部分服务器通过非标准的手段实现了持久连接,但客户端不一定能够支持持久连接。毫无疑问,除了服务器端,客户端也需要支持持久连接。
(2)管线化
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
5、Cookie
HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
响应报文(服务器端生成 Cookie 信息):
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed, 10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
请求报文(自动发送保存着的 Cookie 信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724
6、HTTP 报文
用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。HTTP 报文大致可分为:
- 报文首部:服务器端或客户端处理的请求或响应的内容及属性。
- 报文主体:应发送的数据,不一定有报文主体。
请求报文和响应报文的首部内容由以下数据组成。现在出现的各种首部字段及状态码稍后会进行阐述。
- 请求行:包含用于请求的方法,请求 URI 和 HTTP 版本。
- 状态行:包含表明响应结果的状态码,原因短语和 HTTP 版本。
- 首部字段:包含表示请求和响应的各种条件和属性的各类首部。
(1)编码提升传输速率
HTTP 在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多的 CPU 等资源。
报文和实体
- 报文(message) 是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence,其中 octet 为 8 个比特)组成,通过 HTTP 通信传输。
- 实体(entity)作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。
通常,报文主体等于实体主体。只有进行编码操作时,实体主体和报文主体才产生差异。
压缩传输的内容编码
HTTP 协议使用内容编码对文件进行压缩,常用的内容编码有以下几种:
- gzip(GNU zip);
- compress(UNIX 系统的标准压缩);
- deflate(zlib);
- identity(不进行编码)。
分割发送的分块传输编码
在 HTTP 通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。这种把实体主体分块的功能称为分块传输编码。使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。
HTTP/1.1 中有传输编码机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。
获取部分内容的范围请求
指定范围发送的请求叫做范围请求(Range Request)。对一份 10,000 字节大小的资源,如果使用范围请求,可以只请求 5001~10,000 字节内的资源。
byte 范围的指定形式如下:
- 5001~10,000 字节:
Range: bytes=5001-10000
; - 从 5001 字节之后全部的:
Range: bytes=5001
; - 从一开始到 3000 字节和 5000~7000 字节的多重范围:
Range: bytes=-3000, 5000-7000
。
针对范围请求,响应会返回状态码为 206 Partial Content 的响应报文。另外,对于多重范围的范围请求,响应会在首部字段 Content-Type 标明 multipart/byteranges 后返回响应报文。如果服务器端无法响应范围请求,则会返回状态码 200 OK 和完整的实体内容。
内容协商
内容协商机制是指客户端和服务器端对响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。
包含在请求报文中的某些首部字段就是判断的基准:Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Language。
(2)HTTP 状态码
http 状态码负责表示客户端 http 请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。
状态码的类别:
2XX 成功:2XX 的响应结果表明请求被正常处理了。
- 200 OK:表示从客户端发来的请求在服务器端被正常处理了。
- 204 No Content:代表服务器接收的请求已成功处理,但在返回的响应报文中 不含实体的主体部分。返回 204 响应,那么浏览器显示的页面不发生更新。一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
- 206 Partial Content:该状态码表示客户端进行了范围请求,而服务器成功执行了。响应报文中包含由 Content-Range 指定范围的实体内容。
3XX 重定向:3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
- 301 Moved Permanently:永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI。
- 302 Found:临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。
- 303 See Other:该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。303 和 302 状态码有着相同的功能,但 303 状态码明确表示客户端应当采用 GET 方法获取资源。
- 304 Not Modified:表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件。304 状态码返回时,不包含任何响应的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关系。(附带条件:If-Match,If-ModifiedSince,If-None-Match,If-Range,If-Unmodified-Since)
- 307 Temporary Redirect:临时重定向,该状态码与 302 Found 有着相同的含义。
当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时大家都会这么做。
4XX 客户端错误:4XX 的响应结果表明客户端是发生错误的原因所在。
- 400 Bad Request:该状态码表示请求报文中存在语法错误。
- 401 Unauthorized:该状态码表示发送的请求需要通过 HTTP 认证(BASIC 认证、 DIGEST 认证),但用户认证失败了。
- 403 Forbidden:该状态码表明对请求资源的访问被服务器拒绝了。
- 404 Not Found:该状态码表明服务器上无法找到请求的资源。
5XX 服务器错误:5XX 的响应结果表明服务器本身发生错误。
- 500 Internal Server Error:该状态码表明服务器端在执行请求时发生了错误。
- 503 Service Unavailable:该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入 RetryAfter 首部字段再返回给客户端。
**代理
每次通过代理服务器转发请求或响应时,会追加写入 Via 首 部信息
7、HTTP 报文首部
http 协议的请求和响应报文中必定包含 http 首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。
- 请求报文:在请求中,http 报文由方法、uri、http 版本、http 首部字段等部分构成。
- 响应报文:在响应中,http 报文由 http 版本、状态码(数字和原因短语)、http 首部字段 3 部分构成。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。 HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔。首部字段名:字段值例,如:
- 单个值:Content-Type: text/html
- 多个值:Keep-Alive: timeout=15, max=100
4 种 HTTP 首部字段类型
- 通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部。
- 请求首部字段(Request Header Fields):从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
- 响应首部字段(Response Header Fields):从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
(1)HTTP/1.1 通用首部字段
通用首部字段是指,请求报文和响应报文双方都会使用的首部。
① Cache-Control
通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。指令的参数是可选的,多个指令之间通过“,”分隔。首部字段 CacheControl 的指令可用于请求及响应时。如:Cache-Control: private, max-age=0, no-cache
缓存请求指令:
缓存响应指令:
表示是否能缓存的指令:
- public 指令:当指定使用 public 指令时,则明确表明其他用户也可利用缓存。
- private 指令:当指定 private 指令后,缓存服务器会对该特定用户提供资源缓存的服务,这与 public 指令的行为相反。
- no-cache 指令:使用 no-cache 指令的目的是为了防止从缓存中返回过期的资源。
- 客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。缓存服务器必须把客户端请求转发给源服务器。
- 如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。(Cache-Control: no-cache=Location)
控制可执行缓存的对象的指令:当使用 no-store 指令时,暗示请求(和对应的响应)或响应中包含机密信息。从字面意思上很容易把 no-cache 误解成为不缓存,但事实上 no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源。
指定缓存期限和认证的指令:s-maxage 指令的功能和 max-age 指令的相同,它们的不同点是 s-maxage 指令只适用于供多位用户使用的公共缓存服务器。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。另外,当使用 s-maxage 指令后,则直接忽略对 Expires 首部字段及 max-age 指令的处理。
应用 HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的情况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。而 HTTP/1.0 版本的缓存服务器的情况却相反,max-age 指令会被忽略掉。
min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。比如,当指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响应返回了。
max-stale 指令可指示缓存资源,即使过期也照常接收。如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于 max-stale 指定的时间内,仍旧会被客户端接收。
only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。该指令要求缓存服务器不重新 加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本 地缓存无响应,则返回状态码 504 Gateway Timeout。
must-revalidate 指令表示代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端 一条 504(Gateway Timeout)状态码。 另外,使用 must-revalidate 指令会忽略请求的 max-stale 指令(即使已经在首部使用了 max-stale,也不会再有效果)。
proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
no-transform 指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型(可防止缓存或代理压缩图片等类似操作)。
Cache-Control 扩展通过 cache-extension 标记(token),可以扩展 Cache-Control 首部字段内的指令。仅对能理解它的缓存服务器来说是有意义的。
② Connection
Connection 首部字段具备如下两个作用:
- 控制不再转发给代理的首部字段:在客户端发送请求和服务器返回响应内,使用 Connection 首部字段,可控制不再转发给代理的首部字段(Connection: 不再转发的首部字段名)。
- 管理持久连接:HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。如果想在旧版本的 http 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。
③ Date
首部字段 Date 表明创建 http 报文的日期和时间。
④ Pragma
Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。该首部字段属于通用首部字段,但只用在客户端发送的请求中。如:Pragma: no-cache,客户端会要求所有的中间服务器不返回缓存的资源。所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 CacheControl: no-cache
指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的 HTTP 协议版本却是不现实的。因此,发送的请求会同时含有两个首部字段。
⑤ Trailer
首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在 HTTP/1.1 版本分块传输编码时。
HTTP/1.1 200 OK
Date: Tue, 03 Jul 2012 04:40:56 GMT
Content-Type: text/html
...
Transfer-Encoding: chunked
Trailer: Expires
...(报文主体)...
0
Expires: Tue, 28 Sep 2004 23:59:59 GMT
以上用例中,指定首部字段 Trailer 的值为 Expires,在报文主体之后(分块长度 0 之后)出现了首部字段 Expires。
⑥ Transfer-Encoding
首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。HTTP/1.1 的传输编码方式仅对分块传输编码有效。
⑦ Upgrade
首部字段 Upgrade 用于检测 http 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
客户端:
GET/index.htm HTTP/1.1
Upgrade: TLS/1.0
Connection: Upgrade
服务器:
HTTP/1.1 101 Switching Protocols
Upgrade: TLS/1.0,HTTP/1.1
Connection:Upgrade
上例中,首部字段 Upgrade 指定的值为 TLS/1.0。请注意此处两个字段首部字段的对应关系,Connection 的值被指定为 Upgrade。 Upgrade 首部字段产生作用的 Upgrade 对象仅限于客户端和邻接服务器之间。因此,使用首部字段 Upgrade 时,还需要额外指定 Connection:Upgrade。对于附有首部字段 Upgrade 的请求,服务器可用 101 Switching Protocols 状态码作为响应返回。
⑧ Via
使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文的传输路径。报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信息,然后再进行转发。首部字段 Via 不仅用于追踪报文的转发,还可避免请求回环的发生。所以必须在经过代理时附加该首部字段内容。
Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使用。比如,代理服务器接收到由 TRACE 方法发送过来的请求(其中 Max-Forwards: 0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到 Via 首部后,返回该请求的响应。
⑨ Warning
该首部通常会告知用户一些与缓存相关的问题的警告。Warning 首部的格式如下:(最后的日期时间部分可省略)
Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
HTTP/1.1 警告码:
(2)请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
① Accept
Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒体类型。
- 文本文件:text/html, text/plain, text/css ... application/xhtml+xml, application/xml ...
- 图片文件:image/jpeg, image/gif, image/png ...
- 视频文件:video/mpeg, video/quicktime ...
- 应用程序使用的二进制文件:application/octet-stream, application/zip ...
若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值 1,用分号(;)进行分隔。权重值 q 的范围是 0~1(可精确到小数点后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q=1.0。
② Accept-Charset
Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段 Accept 相同的是可用权重 q 值来表示相对优先级。
③ Accept-Encoding
Accept-Encoding 首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
- gzip:由文件压缩程序 gzip(GNU zip)生成的编码格式;
- compress:由 UNIX 文件压缩程序 compress 生成的编码格式;
- deflate:组合使用 zlib 格式及由 deflate 压缩算法生成的编码格式;
- identity:不执行压缩或不会变化的默认编码格式。
采用权重 q 值来表示相对优先级,这点与首部字段 Accept 相同。另外,也可使用星号(*)作为通配符,指定任意的编码格式。
④ Accept-Language
首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。和 Accept 首部字段一样,按权重值 q 来表示相对优先级。
⑤ Authorization
首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证书值)。如:前后端分离项目,将 token 放入其中来进行用户身份验证。
⑥ Expect
客户端使用首部字段 Expect 来告知服务器,期望出现的某种特定行为。服务器无法理解客户端期望作出的回应而发生错误,会返回状态码 417 Expectation Failed。等待状态码 100 响应的客户端在发生请求时,需要指定 Expect:100continue。
⑦ From
首部字段 From 用来告知服务器使用用户代理的用户的电子邮件地址。使用代理时,应尽可能包含 From 首部字段(但可能会因代理不同,将电子邮件地址记录在 User-Agent 首部字段内)。
⑧ Host
首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
⑨ If-xxx
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
- If-Match:只有当 If-Match 的字段值跟 ETag 值(实体标记 ETag 是与特定资源关联的确定值。资源更新后 ETag 也会随之更新)匹配一致时,服务器才会接受请求。否则返回 412 Precondition Failed (服务器未满足请求者在请求中设置的其中一个前提条件)。
- If-Modified-Since:如果在 If-Modified-Since 字段指定的日期时间后,资源发生了更新,服务器会接受请求,否则返回状态码 304 Not Modified 的响应。用于确认代理或客户端拥有的本地资源(缓存)的有效性,获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确定。
- If-None-Match:只有在 If-None-Match 的字段值与 ETag 值不一致时,可处理该请求。与 If-Match 首部字段的作用相反。
- If-Range:指定的 If-Range 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
- If-Unmodified-Since:首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。它告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应返回。
⑩ Max-Forwards
该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards 的值减 1 后重新赋值。当服务器接收到 Max-Forwards 值为 0 的请求时,则不再进行转发,而是直接返回响应。
⑪ Proxy-Authorization
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。这个行为是与客户端和服务器之间的 HTTP 访问认证相类似的,不同之处在于,认证行为发生在客户端与代理之间。客户端与服务器之间的认证,使用首部字段 Authorization 可起到相同作用。
⑫ Range
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围。接收到附带 Range 首部字段请求的服务器,会在处理请求之后返回状态码为 206 Partial Content 的响应。无法处理该范围请求时,则会返回状态码 200 OK 的响应及全部资源。
⑬ Referer
首部字段 Referer 会告知服务器请求的原始资源的 URI。出于安全性的考虑时,也可以不发送该首部字段。
⑭ TE
首部字段 TE 会告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段 Accept-Encoding 的功能很相像,但是用于传输编码。首部字段 TE 除指定传输编码之外,还可以指定伴随 trailer 字段的分块传输编码的方式。应用后者时,只需把 trailers 赋值给该字段值,如:TE: trailers
⑮ User-Agent
首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传达给服务器。
(3)响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
① Accept-Ranges
首部字段 Accept-Ranges 是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则指定其为 none。
② Age
首部字段 Age 能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段 Age。
③ ETag
首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。当资源更新时,ETag 值也需要更新。
- 强 ETag 值:不论实体发生多么细微的变化都会改变其值。
- 弱 Tag 值:只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
④ Location
使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强制性地尝试对已提示的重定向资源的访问。该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
⑤ Proxy-Authenticate
首部字段 Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端。
⑥ Retry-After
首部字段 Retry-After 告知客户端应该在多久之后再次发送请求。主要配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。字段值可以指定为具体的日期时间,也可以是创建响应后的秒数。
⑦ Server
首部字段 Server 告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。(为了服务器安全,尽量避免显示版本号)
⑧ Vary
首部字段 Vary 可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。当代理服务器接收到带有 Vary 首部字段指定获取资源的请求时,如果使用的 Accept-Language 字段的值相同,那么就直接从缓存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。
⑨ WWW-Authenticate
首部字段 WWW-Authenticate 用于 HTTP 访问认证。它会告知客户端适用于访问请求 URI 所指定资源的认证方案(Basic 或是 Digest)和带参数提示的质询(challenge)。状态码 401 Unauthorized 响应中,肯定带有首部字段 WWW-Authenticate。如:WWW-Authenticate: Basic realm="Usagidesign Auth"
,realm 字段的字符串是为了辨别请求 URI 指定资源所受到的保护策略。
(4)实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
① Allow
首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。
② Content-Encoding
首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。主要采用以下 4 种内容编码的方式:gzip、compress、deflate、identity;
③ Content-Language
首部字段 Content-Language 会告知客户端,实体主体使用的自然语言。
④ Content-Length
首部字段 Content-Length 表明了实体主体部分的大小。对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
⑤ Content-Location
首部字段 Content-Location 给出与报文主体部分相对应的 URI。和首部字段 Location 不同,Content-Location 表示的是报文主体返回资源对应的 URI。
⑥ Content-MD5
客户端会对接收的报文主体执行相同的 MD5 算法,然后与首部字段 Content-MD5 的字段值比较。其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
⑦ Content-Range
针对范围请求,告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。如:Content-Range: bytes 5001-10000/10000
。
⑧ Content-Type
首部字段 Content-Type 说明了实体主体内对象的媒体类型。和首部字段 Accept 一样,字段值用 type/subtype 形式赋值。如:Content-Type: text/html; charset=UTF-8
。
- 表单格式:application/x-www-form-urlencoded;
- 混合格式:multipart/form-data(后边跟 boundary 来告知数据区域分隔符,每个数据都可以单独说明数据类型);
- JSON格式:application/json;
- XML格式:text/xml;
- 文本: text/plain(文本模式,也可以按照文件来接收)。
- 响应报文包含了多个范围的内容时使用:multipart/byteranges,状态码 206(Partial Content,部分内容)。
⑨ Expires
首部字段 Expires 会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。当首部字段 Cache-Control 有指定 max-age 指令时,比起首部字段 Expires,会优先处理 max-age 指令。
⑩ Last-Modified
指明资源最终修改的时间。这个值就是 Request-URI 指定资源被修改的时间。
(5)其他首部字段
在 HTTP 协议通信交互中使用到的首部字段,不限于 RFC2616 中定 义的 47 种首部字段。还有 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定义的首部字段,它们的使用频率也很高。 这些非正式的首部字段统一归纳在 RFC4229 HTTP Header Field Registrations 中。
① End-to-end 首部和 Hop-by-hop 首部
http 首部字段将定义成缓存代理和非缓存代理的行为,分成 2 种类型。
- 端到端首部(End-to-end Header):分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
- 逐跳首部(Hop-by-hop Header):分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部字段。
② Cookie
Cookie 的工作机制是用户识别及状态管理。Web 网站为了管理用户的状态会通过 Web 浏览器,把一些数据临时写入用户的计算机内。Cookie 服务的首部字段:
- Set-Cookie(响应首部字段):开始状态管理所使用的 Cookie 信息,
Set-Cookie: name=value;expires=Tue, 05 Jul 2011 07:26:31;secure
; - Cookie(请求首部字段):服务器接收到的Cookie信息。首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。
③ X-Frame-Options
首部字段 X-Frame-Options 属于 HTTP 响应首部,用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。
- DENY:拒绝;
- SAMEORIGIN:仅同源域名下的页面匹配时许可。
④ X-XSS-Protection
首部字段 X-XSS-Protection 属于 HTTP 响应首部,它是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。
- 0:将 XSS 过滤设置成无效状态;
- 1:将 XSS 过滤设置成有效状态。
⑤ DNT
首部字段 DNT 属于 HTTP 请求首部,表示拒绝被精准广告追踪的一种方法。由于首部字段 DNT 的功能具备有效性,所以 Web 服务器需要对 DNT 做对应的支持。
- 0:同意被追踪;
- 1:拒绝被追踪。
⑥ P3P
首部字段 P3P 属于 HTTP 相应首部,通过利用 P3P 技术,可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
三、HTTP/2.0
HTTP/1.1 标准的不足:
- 一条连接上只可发送一个请求;
- 请求只能从客户端开始。客户端不可以接收除响应以外的指令;
- 请求/响应首部未经压缩就发送,首部信息越多延迟越大;
- 发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
- 可任意选择数据压缩格式,非强制压缩发送。
1、Ajax
Ajax 是异步 JavaScript 与 XML 技术,以达到局部 Web 页面替换加载的异步通信手段。它只更新一部分页面,响应中传输的数据量会因此而减少。
2、Comet
一旦服务器端有内容更新了,Comet 不会让请求等待,而是直接给客户端返回响应。这是一种通过延迟应答,模拟实现服务器端向客户端推送(Server Push)的功能。
服务器端接收到请求,在处理完毕后就会立即返回响应,但为了实现推送功能,Comet 会先将响应置于挂起状态,当服务器端有内容更新时,再返回该响应。为了保留响应,一次连接的持续时间也变长了。期间,为了维持连接会消耗更多的资源。
3、WebSocket
WebSocket 即 Web 浏览器与 Web 服务器之间全双工通信标准。由于是建立在 HTTP 基础上的协议,因此连接的发起方仍是客户端, 而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
- 推送功能:支持服务器主动向客户端推送数据的功能;
- 减少通信量:只要建立起 WebSocket 连接,就一直保持连接状态。WebSocket 的首部信息很小,通信量也相应减少了。
握手·请求
为了实现 WebSocket 通信,需要用到 HTTP 的 Upgrade 首部字段,告知服务器通信协议发生改变,以达到握手的目的。Sec-WebSocket-Key 字段内记录着握手过程中必不可少的键值。Sec-WebSocket-Protocol 字段内记录使用的子协议。
握手·响应
对于之前的请求,返回状态码 101 Switching Protocols 的响应。Sec-WebSocket-Accept 的字段值是由握手请求中的 Sec-WebSocket-Key 的字段值生成的。成功握手确立 WebSocket 连接之后,通信时不再使用 HTTP 的数据帧,而采用 WebSocket 独立的数据帧。
4、SPDY 的设计与功能
SPDY 没有完全改写 HTTP 协议,而是在 TCP/IP 的应用层与运输层之间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY 规定通信中使用 SSL。
- 多路复用流:通过单一的 TCP 连接,可以无限制处理多个 HTTP 请求。所有请求的处理都在一条 TCP 连接上完成,因此 TCP 的处理效率得到提高。(单个域名/IP 地址的通信无法多路复用)
- 赋予请求优先级:可以给请求逐个分配优先级顺序。这样主要是为了在发送多个请求时,解决因带宽低而导致响应变慢的问题。
- 压缩 HTTP 首部:压缩 HTTP 请求和响应的首部。使通信产生的数据包数量和发送的字节数就更少了。
- 推送功能:支持服务器主动向客户端推送数据的功能。
- 服务器提示功能:服务器可以主动提示客户端请求所需的资源。由于在客户端发现资源之前就可以获知资源的存在,因此在资源已缓存等情况下,可以避免发送不必要的请求。
5、HTTP/2.0 的特点
HTTP/2.0 的目标是改善用户在使用 Web 时的速度体验。由于基本上都会先通过 HTTP/1.1 与 TCP 连接,则以下面的这些协议为基础,探讨它们的实现方法。
- SPDY
- HTTP Speed + Mobility:用于改善并提高移动端通信时的通信速度和性能的标准。它建立在 SPDY 与 WebSocket 的基础之上。
- Network-Friendly HTTP Upgrade:主要是在移动端通信时改善 HTTP 性能的标准。
HTTP/2.0 围绕着主要的 7 项技术进行讨论,大都倾向于采用以下协议的技术。但是,讨论仍在持续,所以不能排除会发生重大改变的可能性。
HTTP Speed + Mobility 简写为 Speed + Mobility,Network-Friendly HTTP Upgrade 简写为 Friendly。
标题:HTTP(详解)
作者:Yi-Xing
地址:http://47.94.239.232:10014/articles/2020/12/04/1607074439407.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!