HTTP 协议简介

HTTP 协议采用了非常简单的请求 - 响应模式。由浏览器向网站发出请求(称为 http request),网站根据请求将相关的资源返回给浏览器(称为 http response)。这样周而复始就形成了网络通信。

HTTP 协议是无状态的,也就是说同一个客户端的这次请求和上次请求是独立的,对 http 服务器来说,它并不知道这两个请求来自同一个客户端。为了解决这个问题,在 HTTP 中通过 Session 和 Cookie 机制来维护状态。

HTTP 请求(http request)

消息的结构

HTTP 消息可分为三部分,第一部分叫 request line(请求行), 第二部分叫 http header, 第三部分是 body。下面通过一个例子解释

1
2
3
4
5
6
7
8
9
10
# 第一部分:request line
GET http://www.google.com/ HTTP/1.1
# 第二部分:http header
Host: www.google.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
...
# 第三部分:body(由于请求方法为get,所以body为空)

从上面的例子可以看到: request line 可分为三部分,分别是请求方法 请求资源 使用的协议,上面的例子中,请求的方法是 GET,请求的资源是 http://www.google.com/,使用的 HTTP 协议是 1.1 版本的,也有 1.0 版本的 HTTP 协议,主要区别在于 1.1 版本允许多个 HTTP 请求复用一个 TCP 连接,以加快传输速度

http header 是格式为 key:value 的一系列 kv 对,这些 kv 对主要作用是告知服务器关于浏览器的一些基本信息,如请求的 host、使用的终端类型、页面缓存情况等。具体作用要根据具体的 kv 对分析

body 是发送给服务器的 query 信息 当使用的是 "GET" 方法的时候,body 是为空的(GET 只能读取服务器上的信息,post 能写入)

上面提到的三部分通过换行符 \r\n,其中 request line 永远都是占第一行,接下来每个 header 一行一个,换行符是 \r\n,当遇到连续两个\r\n 时,Header 部分结束,后面的数据全部是 Body

请求的方法

上面提到的 request line 的最后一个部分为请求的方法,在 HTTP 中请求的方法最基本的有 4 种,分别是 GET,POST,PUT,DELETE一个 URL 地址用于描述一个网络上的资源,而 HTTP 中的 GET, POST, PUT, DELETE 就对应着对这个资源的查,改,增,删 4 个操作。

我们最常见的就是 GET 和 POST 了。GET 一般用于获取 / 查询资源信息,而 POST 一般用于更新资源信息. GET 方法和 POST 方法的区别如下:

  • GET 提交的数据会放在 URL 之后,以 ? 分割 URL 和传输数据,参数之间以 & 相连,如 EditPosts.aspx?name=test1&id=123456。POST 方法是把提交的数据放在 HTTP 包的 Body 中。

  • GET 提交的数据大小有限制(因为浏览器对 URL 的长度有限制),而 POST 方法提交的数据没有限制.

  • GET 方式提交数据,会带来安全问题,比如一个登录页面,通过 GET 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.

HTTP 响应(http response)

消息的结构

HTTP 也分为三部分,第一部分叫 response line, 第二部分叫 response header,第三部分是 body。下面是对应着上面的请求的一个响应

1
2
3
4
5
6
7
8
9
10
11
12
13
# 第一部分:response line
HTTP/1.1 302 Found
# 第二部分:response header
Location: http://www.google.com.hk/url?sa=p&hl=zh-CN&pref=hkredirect&pval=yes&q=http://www.google.com.hk/%3Fgws_rd%3Dcr&ust=1465567219496491&usg=AFQjCNGmfj-b-0AJ0D2coSy_40k76XajIw
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Date: Fri, 10 Jun 2016 13:59:49 GMT
Server: gws
Content-Length: 390
Proxy-Connection: keep-alive

# 第三部分:body
....

从上面的例子可以看到: response line 可以分为两部分,分别是使用的 HTTP 协议,状态码及其含义。在上面的例子中使用的协议版本为 1.1,状态码为 302,表示重定向,也就是会向 response 中的 location 表示的 url 发出新的请求。

response header 也是格式为 key:value 的一系列 kv 对,表示服务器的状态和返回的内容的一些信息:如 Content-Type 表明返回的内容的类型,该类型也决定了 body 的内容,如果是网页,Body 就是文本,如果是图片,Body 就是图片的二进制数据;Content-Length 表明返回的内容的类型;Content-Encoding 表示,Body 数据是被压缩的,最常见的压缩方式是 gzip,如 content-Encoding: gzip,压缩的目的在于减少 Body 的大小,加快网络传输。

body 则是返回给浏览器的实际内容,由 content 决定其类型。如上面的例子中返回的类型是 text\html, 则 body 的内容是该网页的 html 代码。如果该 html 代码中还有其他的资源如图片等,浏览器会发送一个新的 http 请求来获取这个资源。

状态码

response line 中的状态码表示对浏览器的请求的回应状况,状态码由三位数字组成,第一个数字定义了响应的类别其中

  • 1XX 提示信息 - 表示请求已被成功接收,继续处理
  • 2XX 成功 - 表示请求已被成功接收,理解,接受
  • 3XX 重定向 - 要完成请求必须进行更进一步的处理
  • 4XX 客户端错误 - 请求有语法错误或请求无法实现
  • 5XX 服务器端错误 - 服务器未能实现合法的请求

一些常见的状态码及其含义如下所示:

  • 200 OK 请求被成功地完成,所请求的资源发送回客户端

  • 302 Found 重定向,新的 URL 会在 response 中的 Location 中返回,浏览器将会使用新的 URL 发出新的 Request

  • 304 Not Modified 文档已经被缓存,直接从缓存调用

  • 400 Bad Request 客户端请求与语法错误,不能被服务器所理解

  • 403 Forbidden 服务器收到请求,但是拒绝提供服务

  • 404 Not Found 请求资源不存在

  • 500 Internal Server Error 服务器发生了不可预期的错误

  • 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常

更多状态码详细解释见 http://tool.oschina.net/commons?type=5