HTTP是不保存状态的协议,协议本身不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事物,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
可是,随着Web的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。
HTTP1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管理状态了。
在HTTP1.1中,所有的连接默认都是持久连接,但在HTTP1.0内并未标准化。虽然有一部分服务器通过非标准化的手段实现了持久连接,但服务器端不一定能够支持持久连接。毫无疑问,除了服务器,客户端也需要支持持久连接。
状态码:
1XX:信息性状态码,表示接收的请求正在处理
2XX:成功状态码,表示请求正常处理完毕。
200:OK
204:No Content
206:Partical Content(指定范围的实体内容)
3XX:重定向状态码,表示需要进行附加操作以完成请求
301:永久性重定向
302:临时性重定向
303:与302有相同的功能,但303状态码明确表示客户端应当采用GET
方法获取资源,这点与302状态码有区别。
304:客户端发送请求,未满足条件的情况下,直接返回304
304状态码的意义:
如果一个网站被搜索引擎抓取的次数以及频率越多那么他是越有利于排名的,但是如果你的网站出现太多的304,那么一定会降低搜索引擎的抓取频率以及次数,从而让自己的网站排名比别人落一步
.
307:和302有相同含义
4XX:客户端错误状态码,表示服务器无法处理请求
400:客户端请求报文中存在语法错误
401:发送请求需要通过HTTP认证,当浏览器初次收到401响应,会弹出认证用的对话窗口
403:客户端请求访问资源,被服务器拒绝了,未获得文件系统的访问权
404:服务器上无法找到请求的资源
5XX:服务器错误状态码,服务器处理请求出错
500:服务器故障
501:服务器暂时超负荷或停机维护
通信数据转发程序:网关、代理、隧道
代理:服务器和客户端中间人的角色。有两种基准分类:1.是否使用缓存 2.是否会修改报文
网关:工作机制和代理相似,网关能使通信线路上的服务器提供非HTTP协议服务。如Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动,提高通信的安全性。
隧道:隧道通信线路会使用SSL等加密手段进行通信,目的是确保客户端与服务器进行安全通信。
HTTP首部
HTTP协议的请求和响应报文中必定包含HTTP首部。
HTTP报文:报文首部+空行+报文主体
HTTP请求报文的报文首部:请求行(报文方法+URI+HTTP版本)+HTTP首部字段(请求首部字段+通用首部字段+实体首部字段)+其他
HTTP响应报文的报文首部:状态行(HTTP版本+状态码)+HTTP首部字段(响应首部字段+通用首部字段+实体首部字段)+其他
HTTP使用首部字段(字段名:字段值)是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
HTTP首部字段:通用首部字段、请求首部字段、响应首部字段、实体首部字段
一 通用首部字段:请求报文和响应报文双方都会使用的首部。
1.Cache-Control:缓存工作机制
1.1 public:表明其他用户可以利用缓存
1.2 private:缓存服务器对特定用户提供资源缓存服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存
1.3 no-cache:直接从服务器获取资源,不从缓存服务器中返回资源
1.4 no-store:请求或响应中包含机密信息。因此缓存不能在本地存储请求或响应的任一部分。
1.5 s-maxage:适用于供多位用户使用的公共缓存服务器。对单一用户重复返回响应的服务器来说,该指令无效。
1.6 max-age:代表资源保存为缓存的最长时间
1.7 min-fresh:缓存服务器返回缓存资源的指定时间,超过则不返回
1.8 max-stale:缓存资源过期也照常接收
1.9 only-if-cached:缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生缓存服务器无响应,则返回状态码504 Gateway Timeout
1.10 must-revalidate:代理会向服务器再次验证即将返回的响应缓存目前是否仍然有效。该指令会忽略请求的max-stale指令
1.11 proxy-revalidate:缓存服务器在接收到客户端带有该指令的请求,在返回响应之前,必须再次验证缓存的有效性。
1.12 no-transform:无论请求还是响应中,缓存都不能改变实体主体的媒体类型,以防止缓存或代理压缩图片等操作。
2.Connection 控制不再转发给代理的首部字段+管理持久连接
HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议想维持持续连接,则需要制定Connection首部字段的值为Keep-Alive。
3.Date 创建HTTP报文的日期和时间
4.Pragma HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。全部服务器使用的HTTP协议版本一致是不现实的,发送请求时会含有下面两个字段:
Cache-Control:no-cache
Pragma:no-cache
5.Trailer 应用在HTTP/1.1版本分块传输编码时
6.Transfer-Encoding 规定了传输报文主体时采用的编码方式
7.Update 用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数可以用来指定一个完全不同的通信协议。
8.Via 追踪客户端与服务器之间的请求和响应报文的传输路径。报文经过代理或网关时,会先在首部字段Via中添加该服务器的信息,然后再进行转发。这个做法和traceroute及电子邮件的Received首部的工作机制很类似。
9.Warning 告知用户一些与缓存相关的问题的警告
二 请求首部字段:客户端往服务器发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
1.Accept 通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。
2.Accept-Charset 通知服务器用户代理支持的字符集及字符集的相对优先顺序。
3.Accept-Encoding 告知服务器用户代理支持的内容编码及内容编码的优先级顺序。
4.Accept-Language 告知服务器用户代理能处理的自然语言集(指中文或英文等),以及自然语言集的相对优先级。可一次指定多种自然语言集。
5.Authorization 告知服务器,用户代理的认证信息
6.Expect 告知服务器,期望出现的某种特定行为
7.From 告知服务器使用用户代理的用户的电子邮件地址
8.Host 告知服务器,请求资源所处的互联网主机名和端口号
9.If-Match 当If-Match的字段值跟ETag值匹配一致时,服务器才会接受请求。
10.If-Modified-Since 告知服务器,若在If-Modified-Since日期后,更新过资源,则处理请求,若未更新过,则返回状态码304Not Modified的响应。
11.If-None-Match If-None-Match字段值的实体标记(ETag)值与请求资源的ETag不一致时,它就告知服务器处理该请求。
12.If-Range 告知服务器若指定的If-Range字段值(ETag值或时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
13.If-Unmodified-Since 告知服务器,若在If-Unmodified-Since字段值后,未更新过资源,则处理请求,若更新过,则返回状态码412 Precondition Failed的响应。
14.Max-Forwards 通过TRACE或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,会将Max-Forwards的值减1后重新赋值。当服务器接收到Max-Forwards的值为0时,则不再进行转发,而是直接返回响应。
15.Proxy-Authorization 从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。认证行为发生在客户端和代理之间,客户端和服务器之间的认证,使用首部字段Authorization可起到相同作用。
16.Range 对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。
17.Refer 首部字段Refer会告知服务器请求的原始资源的URI。
18.TE 告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很相像,但是用于传输编码。
19.User-Agent 将创建请求的浏览器和用户代理名称等信息传达给服务器
三 响应首部字段:响应首部字段是有服务器向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
1.Accept-Ranges 告知客户端 服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。可处理范围请求时指定为:bytes 反之则指定为:none
2.Age 告知客户端,源服务器在多久前创建了响应。单位:秒
3.ETag 客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值。
4.Location 可以将响应接收方引导至某个与请求URI位置不同的资源。
5.Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端
6.Retry-After 告知客户端应该在多久之后再次发送请求
7.Sever 告知客户端当前服务器上安装的HTTP服务器应用程序的信息
8.Vary 对缓存进行控制。如:Vary:Accept-Language 则只对持相同自然语言的请求返回缓存
9.WWW-Authenticate 用于HTTP访问认证
四 实体首部字段:实体首部字段是指包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
1.Allow 通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。
2.Content-Encoding 告知客户端 服务器对实体的主体部分选用的内容编码方式
3.Content-Language 告知客户端,实体主体使用的自然语言(指中文或英文等语言)
4.Content-Length 表明了实体主体部分的大小
5.Content-Location 给出报文主体部分相对应的URI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。
6.Content-MD5 是一串MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
7.Content-Range 针对范围请求,返回响应是使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分以及整个实体大小。例:Content-Range:bytes 5001-10000/10000
8.Content-Type 说明了实体主体内对象的媒体类型
9.Empires 会将资源失效的日期告知客户端
10.Last-Modified 指资源最终修改的时间
Post请求下的Content-Type类型(编码类型)
- application/x-www-form-urlencoded
这应该是最常见的 POST 提交数据的方式了。浏览器的原生
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
首先,Content-Type
被指定为 application/x-www-form-urlencoded
;其次,提交的数据按照 key1=val1&key2=val2
的方式进行编码,key
和 val
都进行了 URL
转码。
- multipart/form-data
这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让
Http协议请求:
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
这个例子稍微复杂点。首先生成了一个 boundary
用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type
里指明了数据是以 multipart/form-data
来编码,本次请求的 boundary
是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary
开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary--
标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。
这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。
上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生