HTTP报文结构
HTTP报文是HTTP协议交互的信息,报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
报文首部一般包含请求行(请求报文)、状态行(响应报文)、首部字段、其他字段等,其中首部字段又分为请求首部字段、响应首部字段、通用首部字段、实体首部字段,除此之外报文首部可能还会包含X-Frame-Options
、X-XSS-Protection
等一些其他字段。
报文首部和报文实体之间用空行(CR+LF)来划分。一个报文通常不一定要有报文实体。
下面我们来看一看请求报文和响应报文的实例。
请求报文
请求报文由请求方法、URI、协议版本、可选的请求首部字段以及实体内容构成,请求方法、URI、协议版本共同组成了请求行,而实体内容并不是每一个请求报文都有。
响应报文
响应报文由协议版本、状态码、解释状态码的原因短语、可选的响应首部字段以及实体内容构成,协议版本、状态码、解释状态码的原因短语共同组成了状态行。
关于状态码的详细说明可以戳我的另一篇学习笔记,返回结果的HTTP状态码。
无状态(stateless)协议
HTTP协议是一种不保存状态的协议,即无状态(stateless)协议。新的请求发送就会有新的响应产生,协议本身不保留之前的请求或响应报文信息。但是随着业务的发展,很多场景需求中都需要掌握之前报文中的信息,例如电商购物网站,登录之后跳转到该站其他页面,也需要保持登录。HTTP/1.1本身是无状态协议,于是为了满足业务需求,网景通信公司开发来了Cookie并制定了标准,这套标准进行扩展之后的产物就是我们现在常用的管理服务器和客户端之前状态的Cookie。
使用Cookie状态管理
Cookie会根据从服务器端发送的响应报文内的Set-Cookie
首部字段通知客户端保存Cookie
。下次客户端再往该服务器发送请求的时候,客户端会自动在请求报文中加入Cookie值后发送出去。如图:
对应的HTTP请求报文和响应报文内容如下:
第 1 步:请求报文
GET /a/1190000005370221 HTTP/1.1
Host: example.com
此时,首部字段内没有Cookie的相关信息。
第 2 步:在响应中添加Cookie返回
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 08:23:37 GMT
Server: Apache
<Set-Cookie: sid=1342077140220000; path=/; expires=Wed,10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
响应报文中有着服务端生成的Cookie信息。
第 3 步:请求报文中添加Cookie后再发送
GET /b/1190000005370221 HTTP/1.1
Host: example.com
Cookie: sid=1342077140220000
请求中自动发送保存着的Cookie信息。
为Cookie服务的首部字段
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 开始状态管理所使用的Cookie信息 | 响应首部字段 |
Cookie | 服务器收到的Cookie信息 | 请求首部字段 |
Set-Cookie
<Set-Cookie: sid=1342077140220000; path=/; expires=Wed,10-Oct-12 07:12:20 GMT; domain=.example.com>
Set-Cookie字段属性:
属性 | 说明 |
---|---|
NAME=VALUE | 赋予Cookie的名称和其值(必须) |
expires=DATE | Cookie的有效期(默认为浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象(默认为文档所在的文件目录) |
domain=域名 | 作为Cookie适用对象的域名(默认为创建Cookie服务器的域名) |
Secure | 仅在HTTPS安全通信时才会发送Cookie |
HttpOnly | 加以限制,使Cookie不能被JavaScript脚本访问 |
Cookie
Cookie: sid=1342077140220000
首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。
持久连接
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接,如图:
当浏览多图的网站时,请求各种图片以及其他资源,将会重复上面这个过程,这会造成无谓的开销。
为解决TCP连接的问题,持久连接的方案应运而生了,持久连接的特点是,只要任意一端没有明确提出断开连接,就保持TCP的连接状态。
然后客户端和服务器端在建立一次TCP连接后的多次请求和响应就变成如下图所示意的那样:
持久连接减少了TCP重复建立和断开所造成的额外开销,减少的重复建立和断开的这部分时间,使HTTP请求和响应能更早的结束,这样页面的显示速度也就快了。
在HTTP/1.1中,所有连接都是持久连接。客户端会在持久连接上连续发送请求。当客户端想断开连接时,则指定Connection
为Close
。
参考
《图解HTTP》
《HTTP权威指南》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。