HTTP协议之:报文详解

时间:2021-03-08 04:34:58

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

HTTP协议的主要特点

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

HTTP报文组成部分

  1. 对报文进行描述的起始行(start line)
  2. 包含属性首部(header)
  3. 包含数据的主体(body)
HTTP/1.0 200 OK //起始行
Content-type:text/plain //首部
Content-length:19 //首部

Hi I'm a message! 主体

HTTP报文语法

所有的报文都可以分为下面两类:
1. 请求报文(request message)
2. 响应报文(response message)

在HTTP请求中:

第一行必须是一个请求行(request line),用来说明请求类型、要访问的资源以及使用的HTTP版本。
在首部之后是一个空行,再此之后可以添加任意的其他数据[称之为主体(body)]。

例如下图:
HTTP协议之:报文详解

//一个请求行(request line)
GET /liuxinmingcode HTTP/1.1
//第一个首部,HOST,结合HOST和上一行中的斜杠(/),可以通知服务器请求的是blog.****.net/liuxinmingcode(HTTP 1.1才需要使用首部HOST,而原来的1.0版本则不需要使用)。
Host
: blog.****.net
//第三行中包含的是首部Connection,keep-alive不关闭连接特性(客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接),Keep-Alive不会永久保持连接,它有一个保持时间.参阅:https://en.wikipedia.org/wiki/HTTP_persistent_connection
Connection
: keep-alive
//用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制),HTTP1.0使用的类似的报头域为Pragma。
请求时的缓存指令包括: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、s-maxage.
eg:为了指示IE浏览器(客户端)不要缓存页面.
Cache-Control
: max-age=0
//Accept请求报头域用于指定客户端接受哪些类型的信息。eg:Accept:image/gif,表明客户端希望接受GIF图象格式的资源;Accept:text/html,表明客户端希望接受html文本。
Accept
: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8

起始行(start line)

请求报文的起始行,或称为请求行。包含了一个方法和一个请求的URL。这个方法描述了服务器应该执行的操作,请求URL描述了要对哪个资源执行这个方法。请求行中还包含HTTP的版本,用来告知服务器,客户端使用的是哪种HTTP版本。

GET /liuxinmingcode HTTP/1.1 #方法为GET URL为/liuxinmingcode HTTP协议版本为1.1

HTTP协议常用方法

方法 描述 是否包含主体
GET 从服务器获取一份文档
HEAD 只从服务器获取文档的首部
POST 向服务器发送需要处理的数据
PUT 将请求的主题部分存储在服务器上
TRACE 对可能经过代理服务器传送到服务器上去的报文进行追踪
OPTIONS 决定可以在服务器执行哪些方法
DELETE 从服务器上删除一份文档

HTTP协议响应状态码

整体范围 已定义范围 分类
100 ~ 199 100 ~ 101 信息提示
200 ~ 299 200 ~ 206 成功
300 ~ 399 300 ~ 305 重定向
400 ~ 499 400 ~ 415 客户端错误
500 ~ 599 500 ~ 505 服务器错误

详细状态:

状态码 原因短语 含义
100 Continue 说明收到了请求的初识部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行响应。
101 Switching Protocols 说明服务器正在根据客户端的指定,将协议切换成Update 首部所列协议
===== ==============================
200 OK 请求成功,实体的主体部分包含了所请求的资源
201 Created 用于创建服务器对象的请求(如:PUT)。响应的尸体主体部分中应该包含各种引用了已创建的资源的URL,Location首部包含的则是具体的引用。
202 Accepted 请求已被接受,但服务器还未对其执行任何动作。不能保证服务器会完成这个请求,这只是意味着接受请求时,它看起来是有效的
203 Non-Authoritative Informaion 实体首部包含的信息不是来自于源端服务器,而是来自资源的一份副本。如果中间节点上有一份资源副本,但无法或者没有对它所发送的与资源有关的元信息进行验证,就会出现这种情况。
204 No Content 响应报文中包含若干首部和一个状态行,但没有实体的主体部分
205 Reset Content 另一个主要用于浏览器的代码。负责告知浏览器清除当前页面中的所有HTML表单元素
206 Partial Content 成功执行了一个部分或Range请求
===== ==============================
300 Multiple Choices 客户端请求一个实际指向多个资源的URL时返回,比如服务器上有某个HTML文档的英文或语法版本。
301 Moved Permanently 永久重定向,告诉客户端以后应从新地址访问.
302 Found 与301状态码类似,但是,客户端应该使用Location首部给出的URL来临时定位资源。
303 See Other 对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。如在文件上传完成后让客户端自动重定向到一个上传成功的结果页面。
304 Not Modified 客户端可以通过所包含的请求首部,使其请求变成有条件的。自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。如果网页自请求者上次请求后再也没有更改过,您应将服务器配置为返回此响应(称为 If-Modified-Since HTTP 标头)。服务器可以告诉 Googlebot 自从上次抓取后网页没有变更,进而节省带宽和开销。
305 Use Proxy 请求者只能使用代理访问请求的网页。如果服务器返回此响应,表示请求者应使用代理。
307 Temporary Redirect 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来响应以后的请求。此代码与响应 GET 和 HEAD 请求的301代码类似,会自动将请求者转到不同的位置,但您不应使用此代码来告诉 Googlebot 某个页面或网站已经移动,因为 Googlebot 会继续抓取原有位置并编制索引。
===== ==============================
400 Bad Request 用于告知客户端它发送了一个错误的请求,服务器不理解请求的语法。
401 Unauthorized 请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。
402 Payment Required 未使用
403 Forbidden 服务器拒绝请求。
404 Not Found 服务器无法找到所请求的URL,例如,对于服务器上不存在的网页经常会返回此代码。
405 Method Not Allowed 禁用请求中指定的方法
406 Not Acceptable 无法使用请求的内容特性响应请求的网页。
407 Proxy Authentication Required 此状态码与 401(未授权)类似,但指定请求者应当授权使用代理。如果服务器返回此响应,还表示请求者应当使用代理。
408 Request Timeout 服务器等候请求时发生超时。
409 Conflict 服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。服务器在响应与前一个请求相冲突的 PUT 请求时可能会返回此代码,以及两个请求的差异列表。
410 Gone 如果请求的资源已永久删除,服务器就会返回此响应。该代码与 404(未找到)代码类似,但在资源以前存在而现在不存在的情况下,有时会用来替代 404 代码。如果资源已永久移动,您应使用 301 指定资源的新位置。
411 Length Required 服务器不接受不含有效内容长度标头字段的请求。
412 Precondition Failed 服务器未满足请求者在请求中设置的其中一个前提条件。
413 Request Entity Too Large 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 Request URI Too Long 请求的 URI(通常为网址)过长,服务器无法处理。
415 Unsupported Media Type 请求的格式不受请求页面的支持。
416 Requested Range Not Satisfiable 如果页面无法提供请求的范围,则服务器会返回此状态码。
417 Expectation Failed 请求的Expect 请求首部包含了一个期望,但服务器无法满足此期望时返回此状态码。
===== ==============================
500 Internal Server Error 服务器遇到错误,无法完成请求。
501 Not Implemented 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
502 Bad Gateway 服务器作为网关或代理,从上游服务器收到无效响应。
503 Service Unavailable 服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
504 Gateway Timeout 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 HTTP Version Not Supported 服务器不支持请求中所用的 HTTP 协议版本。

首部(header)

通用首部

既可以出现在请求报文中,也可以出现在响应报文中。

首部 描述
Connection 允许客户端和服务器指定与请求/响应连接有关的选项
Date 提供日期和时间标志,说明报文时什么时间创建的
MIME-Version 给出了发送端使用的MIME版本
Trailer 如果报文采用了分块传输编码(chunked transfer encoding)方式,就可以用这个首部列出位于报文拖鞋 (trailer)部分的首部集合。
Transfer-Encoding 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
Update 给出了发送端可能想要”升级”使用的新版本或协议
Via 显示了报文经过的中间节点(代理、网关)

通用缓存首部:

首部 描述
Cache-Control 用于随报文传送缓存指示
Pragma 另一种随报文传送指示的方式,但并不专用于缓存

请求首部

请求首部是在请求报文中有意义的首部。用于说明是谁或什么在发送请求,请求源自何处,或者客户端的喜好及能力。服务器可以根据请求首部给出的客户端的信息,试着为客户端提供更好的响应

请求报头举例:

GET /liuxinmingcode HTTP/1.1(CRLF)
Host
: blog.****.net(CRLF)
Connection: keep-alive(CRLF)
Cache-Control: max-age=0(CRLF)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8(CRLF)
Upgrade-Insecure-Requests: 1(CRLF)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36(CRLF)
Accept-Encoding: gzip, deflate, sdch(CRLF)
Accept-Language: zh-CN,zh;q=0.8(CRLF)
(CRLF)
首部 描述
Client-IP 提供了运行客户端的机器的IP地址
From 提供了客户端用户的E-mail地址
Host 给出了接收请求的服务器的主机名和端口号
Referer 提供了包含当前请求URI的文档的URL
UA-Color 提供了与客户端显示器的显示颜色有关的信息
UA-CPU 给出了客户端CPU的类型或制造商
US-Disp 提供了与客户端显示器(屏幕)能力有关的信息
US-OS 给出了客户端显示器的像素信息
UA-Pixels 提供了客户端显示器的像素信息
User-Agent 将发起请求的应用程序名称告知服务器(User-Agent)用户代理,其实不就是浏览器吗

Accept首部

Accept首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括他们想要什么,可以使用什么,以及最重要的,他们不想要什么。这样服务器就可以根据这些额外信息,对要发送的内容做出更明智的决定。Accept首部会使连接的两端都受益。客户端会得到他们想要的内容,服务器则不会浪费其时间和带宽来发送客户端无法使用的东西。

首部 描述
Accept 告诉服务器能够发送哪些媒体类型
Accept-Charset 告诉服务器能够发送哪些字符集
Accept-Encoding 告诉服务器能够发送哪些编码方式
Accept-Language 告诉服务器能够发送哪些语言
TE 告诉服务器可以使用哪些扩展传输编码

条件请求首部

有时客户端希望为请求加上某些限制。比如客户端已经有了一份副本,就希望只在服务器上的文档与客户端拥有的副本有所区别时,才请求服务器传输文档。通过条件请求首部,客户端就可以加上这种限制,要求服务器在对请求进行相应之前,确保某个请求为真。

首部 描述
Expect 允许客户端列出某请求所要求的服务器行为
If-Match 如果实体标记与文档当前的实体标记相匹配,就或者这份文档
If-Modified-Since 除非在某个指定的日期之后资源被修改过,否则就限制这个请求
If-Range 允许对文档的某个范围进行条件请求
If-Unmodified-Since 除非在某个指定的日期之后资源没有被修改过,否则就限制这个请求
Range 如果服务器支持范围请求,就请求资源的指定范围

安全请求首部

代理请求首部

响应首部

响应报文由自己的响应首部集。响应首部为客户端提供了一些额外的信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些首部有助于客户端处理响应,并在将来发起更好的请求。

响应报头举例:

HTTP/1.1 200 OK
Server: openresty
Date: Sun, 20 Dec 2015 07:38:40 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept-Encoding
Cache-Control: private
X-Powered-By: PHP 5.4.28
Content-Encoding: gzip

协商首部

安全响应首部

实体首部

请求和响应消息都可以传送一个实体。一个实体由实体报头域和实体正文组成,但并不是说实体报头域和实体正文要在一起发送,可以只发送实体报头域。实体报头定义了关于实体正文(eg:有无实体正文)和请求所标识的资源的元信息。

内容首部

首部 描述
Content-Base 解析主体中的相对URL时使用的基础URL
Content-Encoding 实体报头域被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。Content-Encoding这样用于记录文档的压缩方法,eg:Content-Encoding:gzip
Content-Language 实体报头域描述了资源所用的自然语言。没有设置该域则认为实体内容将提供给所有的语言阅读者。eg:Content-Language:da
Content-Length 实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
Content-Type 实体报头域用语指明发送给接收者的实体正文的媒体类型。eg:Content-Type:text/html;charset=ISO-8859-1 Content-Type:text/html;charset=GB2312

实体缓存首部

首部 描述
Expires 实体报头域给出响应过期的日期和时间。为了让代理服务器或浏览器在一段时间以后更新缓存中(再次访问曾访问过的页面时,直接从缓存中加载,缩短响应时间和降低服务器负载)的页面,我们可以使用Expires实体报头域指定页面过期的时间。eg:Expires:Thu,15 Sep 2006 16:23:12 GMT HTTP1.1的客户端和缓存必须将其他非法的日期格式(包括0)看作已经过期。eg:为了让浏览器不要缓存页面,我们也可以利用Expires实体报头域,设置为0,jsp中程序如下:response.setDateHeader(“Expires”,”0”);
Last-Modified 实体报头域用于指示资源的最后修改日期和时间。