HTTP(Hypertext Transfer Protocol)即超文本传输协议,是一种用于传输文本、音视频等超媒体(hypermedia)的应用层协议。HTTP从1990年开始就应用于WWW(World Wide Web)服务中,其发展变化与WEB服务紧密相连。这篇文章,就来看看HTTP协议的基本概念。
基本概念
HTTP协议允许不同类型的客户端与服务端进行通讯,支持不同的网络配置,并不依赖于特定的系统。在消息交换过程中,不保存任何状态(state-less,状态无关)。HTTP协议请求基于Request/Response,一个客户端向服务端发送request,该请求包含了Request Method, URL,协议版本以及请求的资源类型;服务端得到请求后,返回一个response,包括状态信息(协议版本,状态码)以及请求的资源。这样一次Request/Response的过程我们称为一次HTTP会话(session),大致有三个阶段:
- 客户端与服务端建立一个TCP链接;
- 客户端发送数据请求,等待回应;
- 服务端处理请求,返回结果并提供一个状态码与资源;
了解TCP/IP的人应该知道,网络协议是一个分层的结构,由物理层、链路层、网络层、传输层以及应用层组成。物理层与链路层负责处理不同网络底层通信细节,如网络接口,网络速率等;网络层主要负责数据的路由,传输层主要负责数据分包、数据重传、拥塞控制,而应用层协议则通常与某个业务需求紧密相关,在某些特定的场景下使用,如HTTP用于WEB应用,而DNS则用于域名解析,FTP协议用于文件传输,EMAIL协议则用于电子邮件的发送与接收。HTTP协议一般通过TCP协议来进行会话,对应的TCP端口为80(有时也会用8080),而对于加密版HTTP协议HTTPS,则使用443端口。
既然HTTP是用于Web中获取资源(这个资源可以是一个文档,一张图片或者一个视频),那么HTTP是如何知道资源所在的位置了?在HTTP,对每个资源都有一个唯一的识别符URI(Uniform Resource Identifier),常见的URI有两种:一种是URL(Uniform Resource Locator),就是我们通常所说的WEB地址;一种是URN(Uniform Resource Name:
URL示例
1 |
|
URN示例
1 |
|
接下来,我们来看下URI是怎么构成的。
URI
如下图是一个URI的结构示意图:
scheme
https://
属于URI的协议部分,用来标识浏览器所使用的协议,对WEB服务来说,通常使用HTTP或者HTTPS协议。常用的scheme有如下几种:
scheme | Description |
---|---|
data | Data URI |
file | host-specific file names |
ftp | File transfer protocol |
http/https | hyper text transfer protocol(secure) |
mailto | electronic mail address |
ssh | secure shell |
tel | telephone |
urn | Uniform Resource Names |
view-source | source code of the resource |
ws/wss | (encrypted) websocket connections |
Authority
tools.ietf.org
又称为域名,该域名标识了一个WEB服务器的地址。通常,我们也可以直接使用该WEB服务器的IP地址来访问,但是在WEB中比较少用。
Port
:443
是HTTP进行数据交换的TCP端口,如果一个WEB服务器使用的是HTTP的标准端口(HTTP:80; HTTPS: 44),则在URI中可以忽略,否则需要特别指出。
Path
/html/rfc7320
表示某个资源在WEB服务器中的路径,通过该路径WEB服务器查找到用户请求的资源。
Query
?query
部分是提供给WEB服务器的额外参数,其通常是如下形式的<key,value>
对:?k1=v1&k2=v2
,例如在使用搜索引擎时,关键词就会以这样的形式呈现给WEB服务器。如下是在Google输入Android后浏览器地址栏显示的部分结果:
1 |
|
Fragment
#section-2.7
可以看做是一个资源某个部分的一个索引或者书签,通过该字段,我们可以直接访问到某个WEB页面的某一部分。需要注意的时,HTTP发送资源请求时,#Fragment
部分并不会发送到服务器,这个部分是由浏览器来处理的, 浏览器会根据这个标签将页面滑动到相应的位置。
HTTP消息
HTTP消息定义了客户端与服务端如何进行数据的交换,这里有两种类型的消息:一种是客户端发送的请求(request),一种是服务端发送的响应(responses)。接下来,就来详细的看下HTTP两类消息的构成。
HTTP请求跟响应总体上结构很相似,主要由四个部分组成(下图所示):
- 一个单一的起始行(start-line):起始行描述的是请求的类型(获取数据还是写入数据)或者服务端响应的状态是成功或者失败。
- HTTP头(headers): 描述请求类型或者消息的主体部分(body);
- 一个空白行用于表示所有元数据(meta-information)已经发送完毕;
- 可选的消息主体(body),如请求的内容或者服务端相应的数据。一般,消息主体的存在以及大小需要在起始行和HTTP头中指定。
HTTP Request
一个HTTP请求由三个部分组成:
- start line;
- http headers;
- body
start line
HTTP的start line用于标识客户端想要服务器执行的某个动作,例如是GET某个数据,还是上传某个数据,其有三个要素组成:
HTTP method:该HTTP请求所要执行的动作,主要有以下几类:
- GET(需要大写): 从服务端获取指定的资源,可以是一个文档,一张图片,一个视频等;
- PUT:创建一个新的资源或者用新的数据取代目标资源;
- POST: 提交某个资源,例如对已存在的资源进行注释;提交一个表单;发布消息到新闻组,邮件列表等;通过附加操作扩展一个数据库;
- DELETE: 删除某个特定的资源;
- TRACE: 用于发起一个远端的回环(loop-back)的消息请求;
- CONNECT: 用于建立一个到服务端的网络隧道(tunnel);
- HEAD: 请求一个与GET命令请求相同的response,但是不包含消息主体(body);
- OPTIONS: 为目标资源描述会话的可选项
请求资源的URL, URL在不同的情况下可以是:
- 绝对路径,通常后面会有一个
?
以及一个查询字符串,一般与GET,POST,HEAD以及OPTIONS搭配使用:POST / HTTP/1.1
,GET /background.png HTTP/1.1
; - 完整的URL,通常连接一个代理服务器时与GET方法一起使用:
GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1
- 一个URL的authority部分,包含了域名跟端口号:
CONNECT developer.mozilla.org:80 HTTP/1.1
- 与OPTIONS方法一起使用的星号(
*
):OPTIONS * HTTP/1.1
- 绝对路径,通常后面会有一个
HTTP版本号,用于告知服务端接收请求响应时所期望的HTTP版本;
HTTP Headers
HTTP头用于客户端向服务端发送关于请求或者响应的额外信息,比如字符的编码方式,语言等,这些信息可以分成如下三个部分:
- 一般性头信息(General Header): 对于请求与响应都适用;
- 请求头信息(Request Header): 关于HTTP请求的附加信息
- 实体头信息(Entity Header): 适用于请求主体(body)的附加信息
有关HTTP头的详细信息可以参考:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
Request Body
通常情况下,HTTP请求不包主体,除非客户端有数据需要更新到服务器上,此时一般由HTTP头Content-Length
,Content-Type
来确定消息体的数据类型以及长度。
HTTP Response
与HTTP请求相类似,HTTP响应也有三部分组成:
- status line: 状态行主要包括HTTP协议版本、状态码以及状态码描述字符串组成。例如
HTTP/1.1 404 NOT FOUND
; - Headers: 响应的头跟请求的头信息有相同的结构(可参考上节关于请求头信息的描述),也包含了三个类型的头信息
- General Headers: 适用于整个消息;
- Response Headers: 描述有关服务端的信息;
- Entity Headers: 适用于消息主体部分;
- body: 并不是所有的HTTP响应都有主体部分,像204,201状态码对应的响应就不需要。
最后一部分,我们来看下服务端响应客户端请求后返回的状态码以及具体的含义。
status code
HTTP的状态码是一个3位数表示,其作用是告知客户端如何解析服务端的响应,共有5种类型的状态码:
1xx: informational
服务端告知客户端继续或者执行某个操作:
- 100: continue, 表示客户端可以继续发送HTTP请求;
- 101: switching protocols, 切换协议;
2xx: Successful
这类状态码用于告知客户端,服务端已经成功收到并处理了HTTP请求:
- 200: OK, 请求成功;
- 202: Accepted, 请求已经被接收到,但是尚未完成处理;
3xx: Redirection
重定向:需要用户的做进一步的操作,通常需要跳至一个不同的URL去获取资源
- 301: moved permanently, 资源已经更换到一个新的URL;
- 303: see other, 需要通过另外一个URL来获取资源;
4xx: Client error
服务端认为客户端出错时发送此状态码,如访问一个无效的资源或者请求有误:
- 400: bad reqeust, 请求有误;
- 401: unauthorized, 请求需要验证;
- 403: forbidden, 服务器拒绝访问资源;
- 404: Not found, 请求的资源不存在
5xx: Server error
此类状态码表示服务器处理请求时出现了错误:
- 500: internal server error, 服务器自身出错;
- 501: not implemented, 服务器尚未实现该请求;
- 503: service unavailable, 服务不用,如服务故障或者过载