一、HTTP协议的概念
1、引子 - 从url开始
URL(Uniform Resource Locator) 地址用于描述一个网络上的资源, 基本格式如下
- schema://host[:port#]/path/.../[?query-string][#anchor]
- scheme 指定低层使用的协议(例如:http, https, ftp)
- host HTTP服务器的IP地址或者域名
- port# HTTP服务器的默认端口是80,这种情况下端口号可以省略。如果使用了别的端口,必须指明,例如 http://www.cnblogs.com:8080/
- path 访问资源的路径
- query-string 发送给http服务器的数据
- anchor- 锚
URL 的一个例子
http://www.mywebsite.com/sj/test/test.aspx?name=sviergn&x=true#stuff
- Schema: http
- host: www.mywebsite.com
- path: /sj/test/test.aspx
- Query String: name=sviergn&x=true
- Anchor: stuff
当我们打开浏览器,在地址栏中输入URL,然后我们就看到了网页。 这个过程中发生了什么呢?
- 我们在浏览器中输入URL回车后,浏览器给Web服务器发送了一个Request请求,
- Web服务器接到Request后进行处理,生成相应的Response,然后发送给浏览器,
- 浏览器解析Response中的HTML,这样我们就看到了网页
过程可能如下图所示
当然,我们的Request 有可能是经过了代理服务器,最后才到达Web服务器的。过程如下图所示
代理服务器也没什么神秘的,代理服务器其实就是一个信息中转站,它可以:
1. 提高访问速度, 大多数的代理服务器都有缓存功能。
2. 突破限制(传说中的FQ?)
3. 隐藏身份。
上面的两个过程中,我们就用到了http协议和tcp/ip协议。
2、名词术语
2.1、TCP/IP协议
术语TCP/IP代表传输控制协议/网际协议,指的是一系列协议。“IP”代表网际协议,TCP和UDP使用该协议从一个网络传送数据包到另一个网络。
如果把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。
TCP和UDP是FTP,HTTP和SMTP之类使用的传输层协议。虽然TCP和UDP都是用来传输其他协议的,它们却有一个显著的不同:TCP提供有保证的数据传输,而UDP不提供。
这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而UDP不提供任何这样的保证。
2.2、什么是http协议
HTTP协议,又叫做超文本传输协议,是关于如何在网络上传输 HTML文档的一种通讯协议。
- HTTP协议采用客户/服务器通信模式: 客户端一般指各种浏览器,服务端一般指各种web服务器。
- HTTP协议建立在TCP/IP协议的基础上,规定了浏览器和web服务器之间的通信细节。
HTTP协议目前最新的版本是1.1,对应RFC2068,http://www.ietf.org/rfc/rfc2068.txt,对http1.1协议做了全面的阐述。目前我们使用的是HTTP/1.1版本。
2.3、TCP/IP、Http的区别
TPC/IP协议是传输层协议,解决的是数据如何在网络中传输的问题;HTTP是应用层协议,解决的是如何包装数据的问题。
我们在传输数据时可以只使用(传输层)TCP/IP协议,但是那样的话没有应用层便无法识别数据内容,要使传输的数据有意义必须使用到应用层协议,
应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。
WEB通讯使用HTTP协议作应用层协议,封装HTTP 文本信息,然后使用TCP/IP做传输层协议将它发到网络上。
HTTP(超文本传输协议)是利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议。客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。
2.4、更深入地,还有 七层传输协议 呢!
下面图表描述TCP/IP和其他的协议在最初OSI模型中的位置:
- 7 应用层 例如HTTP、SMTP、SNMP、FTP、Telnet、SIP、SSH、NFS、RTSP、XMPP、Whois、ENRP
- 6 表示层 例如XDR、ASN.1、SMB、AFP、NCP
- 5 会话层 例如ASAP、TLS、SSH、ISO 8327 / CCITT X.225、RPC、NetBIOS、ASP、Winsock、BSD sockets
- 4 传输层 例如TCP、UDP、RTP、SCTP、SPX、ATP、IL
- 3 网络层 例如IP、ICMP、IGMP、IPX、BGP、OSPF、RIP、IGRP、EIGRP、ARP、RARP、 X.25
- 2 数据链路层 例如以太网、令牌环、HDLC、帧中继、ISDN、ATM、IEEE 802.11、FDDI、PPP
- 1 物理层 例如线路、无线电、光纤、信鸽
二、HTTP协议通讯
1、通讯过程
打开一个网页需要浏览器发送很多次Request
1. 当你在浏览器输入URL http://www.cnblogs.com 的时候,浏览器发送一个Request去获取 http://www.cnblogs.com 的html. 服务器把Response发送回给浏览器.
2. 浏览器分析Response中的 HTML,发现其中引用了很多其他文件,比如图片,CSS文件,JS文件。
3. 浏览器会自动再次发送Request去获取图片,CSS文件,或者JS文件。
4. 等所有的文件都下载成功后。 网页就被显示出来了。
2、会话保持
http协议是无状态的,同一个客户端的这次请求和上次请求是没有对应关系,对http服务器来说,它并不知道这两个请求来自同一个客户端。 为了解决这个问题, Web程序引入了Cookie机制来维护状态.
3、链接保持
HTTP 对 TCP 连接的使用,分为两种方式:俗称“短连接”和“长连接”(“长连接”又称“持久连接”,洋文叫做“Keep-Alive”或“Persistent Connection”)
假设有一个网页,里面包含好多图片,还包含好多【外部的】CSS 文件和 JS 文件。在“短连接”的模式下,浏览器会先发起一个 TCP 连接,拿到该网页的 HTML 源代码(拿到 HTML 之后,这个 TCP 连接就关闭了)。然后,浏览器开始分析这个网页的源码,知道这个页面包含很多外部资源(图片、CSS、JS)。然后针对【每一个】外部资源,再分别发起一个个 TCP 连接,把这些文件获取到本地(同样的,每抓取一个外部资源后,相应的 TCP 就断开)
相反,如果是“长连接”的方式,浏览器也会先发起一个 TCP 连接去抓取页面。但是抓取页面之后,该 TCP 连接并不会立即关闭,而是暂时先保持着(所谓的“Keep-Alive”)。然后浏览器分析 HTML 源码之后,发现有很多外部资源,就用刚才那个 TCP 连接去抓取此页面的外部资源。
在 HTTP 1.0 版本,【默认】使用的是“短连接”(那时候是 Web 诞生初期,网页相对简单,“短连接”的问题不大);
到了1995年底开始制定 HTTP 1.1 草案的时候,网页已经开始变得复杂(网页内的图片、脚本越来越多了)。这时候再用短连接的方式,效率太低下了(因为建立 TCP 连接是有“时间成本”和“CPU 成本”滴)。所以,在 HTTP 1.1 中,【默认】采用的是“Keep-Alive”的方式。
关于“Keep-Alive”的更多介绍,可以参见维基百科词条(在“这里”)
4、HTTP协议是无状态的和Connection: keep-alive的区别
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系
HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)
三、HTTP协议报文
HTTP协议通讯中,客户端和服务器之间的交互通过HTTP消息完成,HTTP消息包括:客户端到服务器的请求、服务器到客户端的响应。
- 请求消息
请求行<CRLF>
消息报头(可选)<CRLF>
<CRLF>(只有CRLF的行)
消息正文(可选)
- 响应消息
响应行<CRLF>
消息报头(可选)<CRLF>
<CRLF>空行(只有CRLF的行)
消息正文(可选)
1、HTTP请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成,请求报文的一般格式如下:
<request-line>
<headers>
<blank line>
[<request-body>]
1.1、请求行
请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔,请求行格式如下:
Method Request-URI HTTP-Version CRLF
例如,GET /index.html HTTP/1.1。
其中,
Method表示请求方法;
Request-URI是一个统一资源标识符;
HTTP-Version表示请求的HTTP协议版本;
CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET 请求获取Request-URI所标识的资源
POST 在Request-URI所标识的资源后附加新的数据
HEAD 请求获取由Request-URI所标识的资源的响应消息报头
PUT 请求服务器存储一个资源,并用Request-URI作为其标识
DELETE 请求服务器删除Request-URI所标识的资源
TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
1.2、请求头部
请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。
请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
1.3、空行
最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
1.4、请求数据
请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
2、HTTP响应报文
HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。如下所示,HTTP响应的格式与请求的格式十分类似:
<status-line>
<headers>
<blank line>
[<response-body>]
如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。
状态行(status line)通过提供一个状态码来说明所请求的资源情况。
下面给出一个HTTP响应报文例子
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>
2.1、状态行
状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操作。
4xx:客户端错误--请求有语法错误或请求无法实现。
5xx:服务器端错误--服务器未能实现合法的请求。
常见状态代码、状态描述
常见状态代码、状态描述的说明如下。
200 OK:客户端请求成功。
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。