HTTP简介

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),大致有三个阶段:

  1. 客户端与服务端建立一个TCP链接;
  2. 客户端发送数据请求,等待回应;
  3. 服务端处理请求,返回结果并提供一个状态码与资源;

HTTP Request-Response

了解TCP/IP的人应该知道,网络协议是一个分层的结构,由物理层、链路层、网络层、传输层以及应用层组成。物理层与链路层负责处理不同网络底层通信细节,如网络接口,网络速率等;网络层主要负责数据的路由,传输层主要负责数据分包、数据重传、拥塞控制,而应用层协议则通常与某个业务需求紧密相关,在某些特定的场景下使用,如HTTP用于WEB应用,而DNS则用于域名解析,FTP协议用于文件传输,EMAIL协议则用于电子邮件的发送与接收。HTTP协议一般通过TCP协议来进行会话,对应的TCP端口为80(有时也会用8080),而对于加密版HTTP协议HTTPS,则使用443端口。

Network Protocol Layer

既然HTTP是用于Web中获取资源(这个资源可以是一个文档,一张图片或者一个视频),那么HTTP是如何知道资源所在的位置了?在HTTP,对每个资源都有一个唯一的识别符URI(Uniform Resource Identifier),常见的URI有两种:一种是URL(Uniform Resource Locator),就是我们通常所说的WEB地址;一种是URN(Uniform Resource Name:

URL示例

1
2
3
4

https://developer.mozilla.org
https://developer.mozilla.org/en-US/docs/Learn/
https://developer.mozilla.org/en-US/search?q=URL

URN示例

1
2
3

urn:isbn:9780141036144
urn:ietf:rfc:7230

接下来,我们来看下URI是怎么构成的。

URI

如下图是一个URI的结构示意图:

URI structure

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
2

https://www.google.co.kr/search?newwindow=1&site=&source=hp&q=Android

Fragment

#section-2.7可以看做是一个资源某个部分的一个索引或者书签,通过该字段,我们可以直接访问到某个WEB页面的某一部分。需要注意的时,HTTP发送资源请求时,#Fragment部分并不会发送到服务器,这个部分是由浏览器来处理的, 浏览器会根据这个标签将页面滑动到相应的位置。

HTTP消息

HTTP消息定义了客户端与服务端如何进行数据的交换,这里有两种类型的消息:一种是客户端发送的请求(request),一种是服务端发送的响应(responses)。接下来,就来详细的看下HTTP两类消息的构成。

HTTP请求跟响应总体上结构很相似,主要由四个部分组成(下图所示):

  1. 一个单一的起始行(start-line):起始行描述的是请求的类型(获取数据还是写入数据)或者服务端响应的状态是成功或者失败。
  2. HTTP头(headers): 描述请求类型或者消息的主体部分(body);
  3. 一个空白行用于表示所有元数据(meta-information)已经发送完毕;
  4. 可选的消息主体(body),如请求的内容或者服务端相应的数据。一般,消息主体的存在以及大小需要在起始行和HTTP头中指定。

HTTP message structure

HTTP Request

一个HTTP请求由三个部分组成:

  • start line;
  • http headers;
  • body

start line

HTTP的start line用于标识客户端想要服务器执行的某个动作,例如是GET某个数据,还是上传某个数据,其有三个要素组成:

  1. HTTP method:该HTTP请求所要执行的动作,主要有以下几类:

    • GET(需要大写): 从服务端获取指定的资源,可以是一个文档,一张图片,一个视频等;
    • PUT:创建一个新的资源或者用新的数据取代目标资源;
    • POST: 提交某个资源,例如对已存在的资源进行注释;提交一个表单;发布消息到新闻组,邮件列表等;通过附加操作扩展一个数据库;
    • DELETE: 删除某个特定的资源;
    • TRACE: 用于发起一个远端的回环(loop-back)的消息请求;
    • CONNECT: 用于建立一个到服务端的网络隧道(tunnel);
    • HEAD: 请求一个与GET命令请求相同的response,但是不包含消息主体(body);
    • OPTIONS: 为目标资源描述会话的可选项
  2. 请求资源的URL, URL在不同的情况下可以是:

    • 绝对路径,通常后面会有一个?以及一个查询字符串,一般与GET,POSTHEAD以及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
  3. HTTP版本号,用于告知服务端接收请求响应时所期望的HTTP版本;

HTTP Headers

HTTP头用于客户端向服务端发送关于请求或者响应的额外信息,比如字符的编码方式,语言等,这些信息可以分成如下三个部分:

  • 一般性头信息(General Header): 对于请求与响应都适用;
  • 请求头信息(Request Header): 关于HTTP请求的附加信息
  • 实体头信息(Entity Header): 适用于请求主体(body)的附加信息

HTTP header

有关HTTP头的详细信息可以参考:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

Request Body

通常情况下,HTTP请求不包主体,除非客户端有数据需要更新到服务器上,此时一般由HTTP头Content-Length,Content-Type来确定消息体的数据类型以及长度。

HTTP Response

与HTTP请求相类似,HTTP响应也有三部分组成:

  1. status line: 状态行主要包括HTTP协议版本、状态码以及状态码描述字符串组成。例如HTTP/1.1 404 NOT FOUND
  2. Headers: 响应的头跟请求的头信息有相同的结构(可参考上节关于请求头信息的描述),也包含了三个类型的头信息
    • General Headers: 适用于整个消息;
    • Response Headers: 描述有关服务端的信息;
    • Entity Headers: 适用于消息主体部分;
  3. 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, 服务不用,如服务故障或者过载

参考文献