# Http协议

HTTP是Hyper Text Transfer Protocol 超文本传输协议,它定义了客户端和服务器端通信时发送数据的格式。它有下面几个特点:

  1. 基于TCP/IP的高级协议,默认端口号:80。
  2. 基于请求/响应模型:一次请求对应一次响应。
  3. 它是无状态的,每次请求之间相互独立,不能交互数据。
  4. HTTP是媒体独立的,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器可指定适合的MIME-type内容类型。

它有几个版本:

  • 1991年,HTTP/0.9 仅支持GET请求,不支持请求头
  • 1996年,HTTP/1.0 默认短连接(一次请求建议一次TCP连接,请求完就断开),支持GET、POST、 HEAD请求
  • 1999年,HTTP/1.1 默认长连接(一次TCP连接可以多次请求);支持PUT、DELETE、PATCH等六种请求。增加host头,支持虚拟主机;支持断点续传功能
  • 2015年,HTTP/2.0 多路复用,降低开销(一次TCP连接可以处理多个请求);服务器主动推送(相关资源一个请求全部推送);解析基于二进制,解析错误少,更高效(HTTP/1.X解析基于文本);报头压缩,降低开销。

HTTP有两个主要报文:请求报文和响应报文,主要包含报文首部和报文主体。

RequestResponse

# HTTP头部

此部分参考Header Field Definitions

通常HTTP消息包括:客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。

# 通用头域

通用头域包含请求和响应消息都支持的头域,对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。

  1. Cache-Control

    Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下:

    • no-cache:指示请求或响应消息不能缓存,实际上是可以存储在本地缓存区中的,只是在与原始服务器进行新鲜度验证之前,缓存不能将其提供给客户端使用。
    • no-store:缓存应该尽快从存储器中删除文档的所有痕迹,因为其中可能会包含敏感信息。
    • max-age:缓存无法返回缓存时间长于max-age规定秒的文档,若不超规定秒浏览器将不会发送对应的请求到服务器,数据由缓存直接返回; 超过这一时间段才进一步由服务器决定是返回新数据还是仍由缓存提供。若同时还发送了max-stale指令,则使用期可能会超过其过期时间。
    • min-fresh:至少在未来规定秒内文档要保持新鲜,接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象。
    • max-stale:指示客户端可以接收过期响应消息,如果指定max-stale消息的值,那么客户端可以接收过期但在指定值之内的响应消息。
    • only-if-cached:只有当缓存中有副本存在时,客户端才会获得一份副本。
    • Public:指示响应可被任何缓存区缓存,可以用缓存内容回应任何用户。
    • Private:指示对于单个用户的整个或部分响应消息,不能被共享缓存处理,只能用缓存内容回应先前请求该内容的那个用户。
  2. Pragma

    Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。

  3. Connection

    Connection表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一 点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。

    • Close:告诉WEB服务器或者代理服务器,在完成本次请求的响应后,断开连接,不要等待本次连接的后续请求了。
    • Keepalive:告诉WEB服务器或者代理服务器,在完成本次请求的响应后,保持连接,等待本次连接的后续请求。
    • Keep-Alive:如果浏览器请求保持连接,则该头部表明希望 WEB 服务器保持连接多长时间(秒),如Keep-Alive:300。
  4. Date

    Date头域表示消息发送的时间,服务器响应中要包含这个头部,因为缓存在评估响应的新鲜度时要用到,其时间的描述格式由RFC822定义。例 如,Date:Mon, 31 Dec 2001 04:25:57 GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。

  5. Transfer-Encoding

    WEB 服务器表明自己对本响应消息体(不是消息体里面的对象)作了怎样的编码,比如是否分块(chunked),例如:Transfer-Encoding: chunked

  6. Upgrade

    它可以指定另一种可能完全不同的协议,如HTTP/1.1客户端可以向服务器发送一条HTTP/1.0请求,其中包含值为“HTTP/1.1”的Update头部,这样客户端就可以测试一下服务器是否也使用HTTP/1.1了。

  7. Via

    列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器,他们用什么协议(和版本)发送的请求。当客户端请求到达第一个代理服务器时,该服务器会在自己发出的请求里面添加 Via 头部,并填上自己的相关信息,当下一个代理服务器 收到第一个代理服务器的请求时,会在自己发出的请求里面复制前一个代理服务器的请求的Via头部,并把自己的相关信息加到后面,以此类推,当 OCS 收到最后一个代理服务器的请求时,检查 Via 头部,就知道该请求所经过的路由。例如:Via:1.0 236-81.D07071953.sina.com.cn:80 (squid/2.6.STABLE13)

# 请求头

Header 解释 示例
Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html
Accept-Charset 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5
Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型。 Accept-Encoding: compress, gzip
Accept-Language 浏览器可接受的语言 Accept-Language: en,zh
Accept-Ranges 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes
Authorization HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache
Connection 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close
Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;
Content-Length 请求的内容长度 Content-Length: 348
Content-Type 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded
Date 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect 请求的特定的服务器行为 Expect: 100-continue
From 发出请求的用户的Email From: user@email.com
Host 指定请求的服务器的域名和端口号 Host: www.zcmhi.com
If-Match 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards 限制信息通过代理和网关传送的时间 Max-Forwards: 10
Pragma 用来包含实现特定的指令 Pragma: no-cache
Proxy-Authorization 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 只请求实体的一部分,指定范围 Range: bytes=500-999
Referer 先前网页的地址,当前请求网页紧随其后,来源网址 Referer: http://www.zcmhi.com/archives/71.html
TE 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5
Upgrade 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11)
Via 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 关于消息实体的警告信息 Warn: 199 Miscellaneous warning

# 响应头

Header 解释 示例
Accept-Ranges 表明服务器是否支持指定范围请求及哪种类型的分段请求 Accept-Ranges: bytes
Age 从原始服务器到代理缓存形成的估算时间(以秒计,非负) Age: 12
Allow 对某网络资源的有效的请求行为,不允许则返回405 Allow: GET, HEAD
Cache-Control 告诉所有的缓存机制是否可以缓存及哪种类型 Cache-Control: no-cache
Content-Encoding web服务器支持的返回内容压缩编码类型 Content-Encoding: gzip
Content-Language 响应体的语言 Content-Language: en,zh
Content-Length 响应体的长度 Content-Length: 348
Content-Location 请求资源可替代的备用的另一地址 Content-Location: /index.htm
Content-MD5 返回资源的MD5校验值 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range 在整个返回体中本部分的字节位置 Content-Range: bytes 21010-47021/47022
Content-Type 返回内容的MIME类型 Content-Type: text/html; charset=utf-8
Date 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
ETag 请求变量的实体标签的当前值 ETag: “737060cd8c284d8af7ad3082f209582d”
Expires 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT
Last-Modified 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Location 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 Location: http://www.zcmhi.com/archives/94.html
Pragma 包括实现特定的指令,它可应用到响应链上的任何接收方 Pragma: no-cache
Proxy-Authenticate 它指出认证方案和可应用到代理的该URL上的参数 Proxy-Authenticate: Basic
refresh 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) Refresh: 5; url=http://www.zcmhi.com/archives/94.html
Retry-After 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 Retry-After: 120
Server web服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
Set-Cookie 设置Http Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Trailer 指出头域在分块传输编码的尾部存在 Trailer: Max-Forwards
Transfer-Encoding 文件传输编码 Transfer-Encoding:chunked
Vary 告诉下游代理是使用缓存响应还是从原始服务器请求 Vary: *
Via 告知代理客户端响应是通过哪里发送的 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 警告实体可能存在的问题 Warning: 199 Miscellaneous warning
WWW-Authenticate 表明客户端请求实体应该使用的授权方案 WWW-Authenticate: Basic

# 实体头

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充实体相关信息,包括实体信息类型,长度,压缩方法,最后一次修改时间,数据有效性等。

Header 解释
Allow 服务器支持哪些请求方法(如GET、POST等)。
Location 表示客户应当到哪里去提取文档,用于将接收端定位到资源的位置(URL)上。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
Content-Base 解析主体中的相对URL时使用的基础URL。
Content-Encoding WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象。例如:Content-Encoding:gzip
Content-Language WEB 服务器告诉浏览器理解主体时最适宜使用的自然语言。
Content-Length WEB服务器告诉浏览器自己响应的对象的长度或尺寸,例如:Content-Length: 26012
Content-Location 资源实际所处的位置。
Content-MD5 主体的MD5校验和。
Content-Range 实体头用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长 度。一般格式: Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth。例如,传 送头500个字节次字段的形式:Content-Range:bytes0- 499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范 围,Content-Length表示实际传送的字节数。
Content-Type WEB 服务器告诉浏览器自己响应的对象的类型。例如:Content-Type:application/xml
Etag 就是一个对象(比如URL)的标志值,就一个对象而言,比如一个html文件,如果被修改了,其Etag也会别修改,所以,ETag的作用跟 Last-Modified的作用差不多,主要供WEB服务器判断一个对象是否改变了。比如前一次请求某个html文件时,获得了其 ETag,当这次又请求这个文件时,浏览器就会把先前获得ETag值发送给WEB服务器,然后WEB服务器会把这个ETag跟该文件的当前ETag进行对 比,然后就知道这个文件有没有改变了。
Expires WEB服务器表明该实体将在什么时候过期,对于过期了的对象,只有在跟WEB服务器验证了其有效性后,才能用来响应客户请求。是 HTTP/1.0 的头部。例如:Expires:Sat, 23 May 2009 10:02:12 GMT
Last-Modified WEB服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT

# 请求报文

示例如下:

POST /login.html	HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost/login.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1

username=zhangsan
1
2
3
4
5
6
7
8
9
10
11

请求报文主要包含:

  1. 请求行格式如下:
    请求方式 请求url 请求协议/版本
    GET /login.html HTTP/1.1
    • HTTP协议有7中请求方式:
      • GET:向Web服务器请求一个文件。
      • POST:向Web服务器发送数据让Web服务器进行处理。
      • PUT:向Web服务器发送数据并存储在Web服务器内部。
      • HEAD:检查一个对象是否存在。
      • DELETE:从Web服务器上删除一个文件。
      • CONNECT:对通道提供支持。
      • TRACE:跟踪到服务器的路径。
      • OPTIONS:查询Web服务器的性能。
    • 其中常用的有GET和POST,它们的区别如下:
      • GET:
        1. 请求参数在请求行中,在url后。
        2. 请求的url长度有限制的
        3. 不太安全
      • POST:
        1. 请求参数在请求体中
        2. 请求的url长度没有限制的
        3. 相对安全
  2. 请求头:客户端浏览器告诉服务器一些信息,请求头格式一般是(请求头名称: 请求头值)。常见的请求头:
    1. User-Agent:浏览器告诉服务器所使用的浏览器版本信息,可以在服务器端获取该头的信息,解决浏览器的兼容性问题。
    2. Referer:告诉服务器,我(当前请求)从哪里来?它的作用主要有:防盗链和统计工作。
  3. 请求空行,它是空行,用于分割POST请求的请求头和请求体的。
  4. 请求体(正文):封装POST请求消息的请求参数的。

# 响应报文

响应报文示例如下:

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMT

<html>
  <head>
    <title>测试</title>
  </head>
  <body>
  hello world
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13

响应报文主要包含:

  1. 响应行,它的格式如下:
    协议/版本 响应状态码 状态码描述
  2. 响应头,它的格式一般是(头名称:值)。常见的响应头如下:
    1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
    2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据
      • in-line:默认值,在当前页面内打开
      • attachment;filename=xxx:以附件形式打开响应体。文件下载
  3. 响应空行
  4. 响应体:传输的数据

响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态。状态码都是3位数字,此处摘自HTTP状态码

RespondCode