HTTP协议
HTTP协议
以HTTP/1.1为例,首先我们先了解访问网站时做了哪些操作:
1 URI
1.1 URL与URI
-
URI与URL的关系是:URI包含URL;
-
URL(Uniform Resource Locator,统一资源定位符) 即使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。比如,上图的要访问的
http://hackr.jp/
就是 URL。 -
URI(Uniform Resource Identifier, 统一资源标识符) 即,由某个[1]表示的资源的定位标识符。
1.2 URI 格式
1.2.1 绝对URI格式:
- 协议方案名:用于指定协议类型。不区分字母大小写,最后附一个 ":"。
- 登录信息(认证) : 指定用户名和密码。(可选)
- 服务器地址: 指定待访问的服务器地址。IPv6地址需要用方括号括起来:[::1] 。
- 服务器端口号: 指定访问服务器的端口号。(可选)
- 带层次的文件路径(相对URL): 指定服务器上的文件路径来定位特指的资源。
- 查询字符串: 针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。
- 片段标识符: 通常可标记出已获取资源中的子资源(文档内的某个位置)。(可选)
2 HTTP 协议通信方式
2.1 客户/服务器模式
请求必定由客户端发出,服务器端回复响应。
每个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。
2.2 无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
2.3 无状态
HTTP 协议自身不对请求和响应之间的通信状态进行保存。一方面,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2.4 持久连接解决方案
使用浏览器浏览一个包含多张图片的HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。
为解决上述 TCP 连接的问题,提出了 HTTP keep-alive 持久连接方案。
- 只要任意一端没有明确提出断开连接,则保持TCP 连接状态。
- 在 HTTP/1.1 中,所有的连接默认都是持久连接。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
2.5 无状态解决方案
假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次请求报文中附加参数来管理登录状态。另外,如果让服务器管理全部客户端状态则会成为负担。
为了保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
3 HTTP 方法
-
GET: 请求获取 Request-URI 所标识的资源。
-
POST: 在 Request-URI 所标识的资源后附加新的数据。
如果不是访问特定资源而是对服务器本身发起请求,可以用一个 * 来代替请求 URI。 如:查询 HTTP 服务器端支持的HTTP 方法种类。 OPTIONS * HTTP/1.1
-
PUT: 请求服务器存储上传的资源,保存到 Request-URI 指定的位置。
-
HEAD: 请求获取由 Request-URI 所标识的资源,不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。
-
DELETE: 按 Request-URI 删除指定的资源。
-
OPTIONS: 查询针对请求 URI 指定的资源支持的方法。
-
TRACE: 让 Web 服务器端将之前的请求通信返回给客户端。发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器端就将该数字减 1,当数值刚好减到 0 时,就停止继续传输,最后接收到请求的服务器端则返回状态码 200 OK 的响应。
-
CONNECT: 要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL 和 TLS 协议把通信内容加密后经网络隧道传输。格式:
CONNECT 代理服务器名:端口号 HTTP版本
。
4 HTTP 报文
HTTP 报文大致可分为报文首部和报文主体两块。两者由最初出现的空行(CR+LF)来划分。通常,并不一定要有报文主体。
4.1 请求行
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:
GET / HTTP/1.1
Method Request-URI HTTP-Version CR+LF
Method:求方法;
Request-URI:请求访问的资源对象;
HTTP-Version:请求的HTTP协议版本;
CRLF:表示回车和换行。
4.2 状态行
请求行以HTTP版本开头,以空格分开,后面跟着状态码和原因短语,格式如下:
HTTP/1.1 200 OK
HTTP-Version Status-Code Reason-Phrase CR+LF
HTTP-Version:HTTP版本;
Status-Code:表明响应结果的状态码;
Reason-Phrase:原因短语。
4.3 首部字段
HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分隔。
首部字段名: 字段值
4.3.1 通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建HTTP报文的日期时间 |
Pragma | 向后兼容指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
4.3.2 请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与 If-Match 相反) |
If-Range | 资源未更新时发送实体 Byte 的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中 URI 的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP 客户端程序的信息 |
4.3.3 响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
4.3.4 实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
4.3.5 其他首部字段
-
Cookie 服务的首部字段
-
Set-Cookie:当服务器准备开始管理客户端的状态时,会事先告知各种信息。
- NAME=VALUE:赋予 Cookie 的名称和其值(必需项)
- expires=DATE:指定浏览器可发送 Cookie的有效期。其有效期仅限于维持浏览器会话(Session)时间段内。通常限于浏览器被关闭之前。另外,可通过覆盖已过期的 Cookie,实现对客户端Cookie 的实质性删除操作。
- path 属性:Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。(有办法避开该限制)
- domain 属性:通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致。比如,当指定 example.com 后,除 example.com 以外,www.example.com 或www2.example.com 等都可以发送 Cookie。
- secure 属性:用于限制 Web 页面仅在HTTPS 安全连接时,才可以发送 Cookie。当省略 secure 属性时,不论 HTTP 还是 HTTPS,都会对 Cookie 进行回收。反之,不会回收。
- HttpOnly 属性:使 JavaScript 脚本无法获得 Cookie。其主要目的为防止跨站脚本攻击(Cross-site scripting,XSS)对 Cookie 的信息窃取。
-
Cookie:
Cookie: status=enable
。告知服务器,当客户端想获得HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。接收到多个 Cookie 时,同样可以以多个 Cookie 形式发送。
-
-
X-Frame-Options:用于控制网站内容在其他 Web 网站的 Frame标签内的显示问题。其主要目的是为了防止点击劫持(clickjacking)攻击。
- DENY :拒绝
- SAMEORIGIN :仅同源域名下的页面(Top-level-browsing-context)匹配时许可。
-
X-XSS-Protection:针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关。
- 0 :将 XSS 过滤设置成无效状态
- 1 :将 XSS 过滤设置成有效状态
-
DNT: Do Not Track 的简称,表示拒绝被精准广告追踪的一种方法。
- 0 :同意被追踪
- 1 :拒绝被追踪
-
P3P:(The Platform for Privacy Preferences,在线隐私偏好平台)可以让 Web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
- 要进行 P3P 的设定,需按以下操作步骤进行。
- 步骤 1:创建 P3P 隐私
- 步骤 2:创建 P3P 隐私对照文件后,保存命名在/w3c/p3p.xml
- 步骤 3:从 P3P 隐私中新建 Compact policies 后,输出到 HTTP 响应中
- 要进行 P3P 的设定,需按以下操作步骤进行。
4.3.6 End-to-end 首部和 Hop-by-hop 首部
HTTP 首部字段将定义成缓存代理和非缓存代理的行为,分成 2 种类型。
端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求 / 响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供Connection 首部字段。
除这 8个逐跳首部字段之外,其他所有字段都属于端到端首部。
- Connection
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
4.4 编码
4.4.1 报文主体和实体主体的差异
报文(message)
- 是 HTTP 通信中的基本单位,由 8 位组字节流(octet sequence,其中 octet 为 8 个比特)组成,通过 HTTP 通信传输。
实体(entity)
- 作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。
4.4.2 内容编码
内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。常用的内容编码有以下几种:
- gzip(GNU zip)
- compress(UNIX 系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
4.4.3 分块传输编码
分块传输编码(Chunked Transfer Coding):会将实体主体分成多个部分(块)。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记。
4.5 HTTP 多部分对象集合
HTTP 协议中采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体(如:文本、图片、视频)。包含的对象如下:
multipart/form-data:在 Web 表单文件上传时使用。
multipart/byteranges:状态码 206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。
multipart/form-data:文件的数据
multipart/byteranges:范围指定的数据
4.6 范围请求
指定范围发送的请求。指定形式如下:
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 和完整的实体内容。
4.7 内容协商
内容协商(Content Negotiation):当浏览器的默认语言为英语或中文,访问相同URI 的 Web 页面时,则会显示对应的英语版或中文版的 Web 页面。
判断的基准是请求报文中的某些首部字段:
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
种内容协商技术
- 服务器驱动协商(Server-driven Negotiation)
- 由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。
- 客户端驱动协商(Agent-driven Negotiation)
- 由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。
- 透明协商(Transparent Negotiation)
- 是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。
5 响应状态码
类别 | 原因短语 | |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求,请求有语法错误或请求无法实现 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
2XX
- 200 OK:表示从客户端发来的请求在服务器端被正常处理了。
- 204 No Content:表示服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
- 206 Partial Content:表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
3XX
- 301 Moved Permanently:永久性重定向。表示请求的资源已被分配了新的 URI,以后应使用该资源现在所指的URI。如请求URI时,指定资源路径的最后忘记添加斜杠“/”,就会产生 301 状态码。
- 302 Found:临时性重定向。表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的URI 访问。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。
- 303 See Other:表示由于请求对应的资源存在着另一个URI,使用 GET 方法定向获取请求的资源。303 状态码明确表示客户端应当采用 GET 方法获取资源。
- 304 Not Modified: 表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应的主体部分。304和重定向没有关系。
- 307 Temporary Redirect:临时重定向。与 302 Found 相同但不会从 POST 变成GET。
4XX
- 400 Bad Request:表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
- 401 Unauthorized:表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用 户认证失败。这个状态代码必须和WWW-Authenticate报头域一起使用。
- 403 Forbidden:对请求资源的访问被服务器拒绝了。
- 404 Not Found:服务器上无法找到请求的资源。
5XX
- 500 Internal Server Error:服务器端在执行请求时发生了错误。
- 503 Service Unavailable:服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
脚注
协议方案指访问资源所使用的协议类型名称。如 http:、ftp:、telent: 等。 ↩︎