概述
HTTP(Hypertext transfer Protocol)超文本传输协议,用于Web应用开发时,客户端和服务器之间的通信协议。HTTP是一个纯文本的通信协议,HTTP最新的版本是HTTP1.1,兼容HTTP1.0版本的协议,RFC2616描述了HTTP1.1相关的内容,可以这里获取到最新的HTTP RFC文档。
基本结构
与其他的通信协议类似,HTTP协议也是由消息头和消息体组成的。下面是HTTP通信时的几点约定:
- 以行作为基本的传输单元,每行以回车 换行(C语言里是“\r\n”)结尾。
- 消息头和消息体用空行隔开(只有一个回车换行)。
- 如果没有消息体的话, 同样也是由空行结束消息头。
HTTP通信事务一般包括一个客户端发起的请求消息和服务器返回的响应消息,请求消息和响应消息都有特定的消息格式,消息头和消息体的定义也各不相同。
请求消息
消息头
HTTP通信过程一般由客户端(比如浏览器)发起,请求消息的基本格式如下:
(1个)请求行 + (0或多个)请求报头 + 结束行空行(回车+换行)
请求行
请求行一般格式如下:
method + URI + version
-
method包括:GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE,其中以GET和POST最为常用。
-
URI(Uniform Resource Identifier),即统一资源识别符,表示一些资源的标识方法,其一般包括文件名和可选的参数。
-
URL(Universal Resource Locator),通用资源定位符。每条Web服务器返回的内容都是和一个它管理的文件相关联的,每一个文件都一个唯一的名字,就叫做URL,例如:
http://www.baidu.com:80/index.html
表示index.html这个文件,保存在地址为www.baiud.com,端口为80的这台机器上。可以在URL的末尾添加相应的参数,
参数以?开始,每个参数之间以&分开,比如:
http://www.baidu.com:80/index.html?type=1
关于URL中的后缀有几点需要注意:
- URL中第一个“/”表示的是被请求内容类型的主目录,对于一个Web服务器而且,一般指服务器程序的运行目录。
- 最小的URL后缀是“\”,所有的Web服务器将其扩展为某个默认的主页,比如,/index.html,这解释了,如果在浏览器中简单的输入一个服务的域名之后就可以访问网站的默认主页的原因。
- URI一般作为URL的后缀出现,比如,上面的URL中
http://www.baidu.com:80/index.html?type=1
URI为:index.html?type=1
- HTTP携带参数的方式分为两种:
- GET请求:GET请求将参数置于URI中,例如,第4中的URI所示。
- POST请求:POST请求的参数在请求消息体,而不是在URI中。
- version字段表明该请求消息所遵循的HTTP协议版本,如上所述,最新的HTTP版本为HTTP/1.1,HTTP/1.0是从1995沿用至今的老版本,HTTP/1.1增加了一些新的附加报头,比如缓冲机制和安全等级,以及允许客户端和服务器之间建立一条持久连接机制,即websocket技术。
请求报头
请求报头为服务器提供了额外的信息,例如浏览器的信息、操作系统的信息、浏览器所支持的MIME类型。请求报头是分行设置的,每行表示一个请求报头,其格式如下:
header-name:header-data
比如,这是通过firfox向一个echo服务器发送请求时的所包含的请求报头,
Host: localhost:5000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;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
Connection: keep-alive
其中,关于各个报头的含义,可以参考RFC2616。
消息体
一般GET方法的请求消息不会包含消息,而POST方法由于请求参数必须包含在消息体中,所以需要提供消息体。比如下面的POST请求消息,就用到了消息体。
POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}
响应消息
HTTP的响应消息也是由消息头和消息体组成的,其格式如下:
(1个)响应行 + (0个或多个)响应报头 + "回车+换行" + 响应消息体
消息头
消息头包括,响应行和0个或多个响应报头,下面是一个消息头的示例:
HTTP/1.0 200 OK
MIME-Version: 1.0
Date: Mon, 8 Jan 2010 4:59:42 GMT
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 42092
响应行
响应行的格式如下:
version + status-code + status-message
- version描述的是响应字段所遵循的HTTP版本。
- status-code是一个3位正整数,指明对于请求的处理状态。
- status-message给出与状态码相对应的英文描述。
常用的HTTP状态码如下表所示,更多的状态码,请参考RFC2616。
状态码 | 状态消息 | 描述 |
---|---|---|
200 | OK | 处理请求无误 |
301 | Moved Permanently | 内容已经移动到location头中指明的主机上 |
400 | Bad Request | 服务器不能理解该请求 |
403 | Forbidden | 服务器无权访问所请求的文件 |
404 | Not Found | 服务器不能找到所请求的文件 |
501 | Not Implemented | 服务器不支持请求的方法 |
505 | HTTP Version Not Supported | 服务器不支持请求的版本 |
响应报头
响应报头提供了关于响应消息的附加信息,其格式如下:
header-name:header-data
其中,两个比较重要的报头是:
- Content-Type,表示服务器响应的消息体内容的MIME类型。
- Content-Length,表示响应消息体的字节大小。
消息体
Web服务器返回的响应消息的消息体是一个与MIME(Multipurpose Internet Mail Extensions,多用途的网际邮件扩充协议)类型相关的字节序列,下面是一些常用的MIME类型。
MIME类型 | 描述 |
---|---|
text/html | HTML页面 |
text/plain | 无格式文本 |
application/xml | xml格式数据 |
application/xml | json格式数据 |
image/gif | GIF格式编码的二进制图像 |
image/png | PNG格式编码的二进制图像 |
Web服务器以两种不同的方式向客户端提供服务:
- 静态内容,服务器读取本地磁盘上一个文件,比如,home.html,并将文件内容返回给客户端,这个过程叫做服务静态内容(serving static content)。
- 动态内容,服务器运行本地一个可执行程序或者一段可执行的代码,根据客户端提供的参数,得到客户端想要的内容,并返回给客户端,这个过程叫做服务动态内容(serving dynamic content)。