在 HTTP 通信链上,客户端和目标服务器之间通常存在某些中转代 理服务器,它们提供对目标资源的中转访问。一个 HTTP 请求可能被多个代理服务器转发,后面的服务器称为前面服务器的上游服务器。代理服务器按照其使用方式和作用,分为正向代理服务器、反向代理服务器和透明代理服务器:
代理服务器通常提供缓存功能,因此访问同一资源时速度很快,优秀的代理软件如下:
GET http://www.baidu.com/index.html HTTP/1.0
User-Agent:Wget/1.12(linux-gnu)
Host:www.baidu.com
Connection:close
第 1 行是请求行,GET 是请求方法,表示客户端以只读的方式来申请资源,常见的请求方法有 9 种:
请求方法 | 性质 | 含义 |
---|---|---|
GET | 安全、等幂的 | 申请获得资源,而不对服务器产生任何其他影响 |
HEAD | 安全、等幂的 | 和 GET 类似,仅要求服务器返回头部信息,不需要传输任何实际内容 |
POST | 客户端向服务器提交数据的方法,会对服务器数据进行修改(增删改) | |
PUT | 等幂的 | 上传某个资源 |
DELETE | 等幂的 | 删除某个资源 |
TRACE | 安全、等幂的 | 要求目标服务器返回原始 HTTP 请求的内容,可用来查看中间服务器对 HTTP 请求的影响 |
OPTIONS | 安全、等幂的 | 查看服务器对某个特定 URL 都支持哪些请求方法。也可把 URL 设置为 * ,从而获得服务器支持的所有请求方法 |
CONNECT | 用于某些代理服务器,能把请求的连接转化为一个安全隧道 | |
PATCH | 对某个资源做部分修改 |
http://www. baidu.com/index.html
是目标资源的 URL ,其中 http
是所谓的 scheme ,表示获取目标资源需要使用的应用层协议,其他常见的 scheme 还有 ftp 、rtsp 、file 等。www.baidu.com
指定资源所在的目标主机;index.html
指定资源文件的名称,这里指的是服务器根目录(站点的根目录,而不是雾浮起的文件系统根目录 /
)种的索引文件。HTTP/1.0
表示客户端按(wget 程序)使用的 HTTP 的版本号是 1.0 ,目前主流版本是 1.1 。
第 2 ~ 4 行都是 HTTP 请求的头部字段,一个 HTTP 请求可以包含多个头部字段,一个头部字段用一行表示,包含字段名称、冒号、空格和字段的值。HTTP 请求中的头部字段可按任意顺序排列。
User-Agent:Wget/1. 12(linux-gnu)
表示客户端使用的程序是 wget ;Host:www. baidu.com
表示目标主机名是 www.baidu.com
,HTTP 协议规定 HTTP 请求中必须包含的头部字段就是目标主机名;Connection:close
是执行 wget 命令时传入的,用以告诉服务器处理完这个 HTTP 请求之后就关闭连接。在旧的 HTTP 协议中,Web 客户端和 Web 服务器之间的一个 TCP 连接只能为一个 HTTP 请求服务。当处理完客户的一个 HTTP 请求后,Web 服务器就主动将 TCP 连接关闭。此后同一客户如果要再发送一个 HTTP 请求,必须与服务器建立一个新的 TCP 连接,这称为短连接。
相对的,多个请求可以使用同一个 TCP 连接的方式称为长连接,在编码上复杂度更高,但性能明显提高,极大地减少了网络上为建立 TCP 连接导致的负荷,同时对每次请求而言缩减了处理时间。
Connection 字段专门用于告诉对方一个请求完成之后该如何处理连接:
用浏览器访问网页时,可以使用 netstat 命令查看浏览器和 Web 服务器之间的连接是否为长连接,以及该连接维持了多长时间。
在所有头部字段之后,HTTP 请求必须包含一个空行,以标识头部字段的结束。请求行和每个头部字段都必须以
空行之后,HTTP 请求可以包含可选的消息体,如果消息体非空,则 HTTP 请求的头部中必须包含描述该消息体长度的字段:Content-Length 。
HTTP/1.0 200 OK
Server:BWS/1.0
Content-Length:8024
Content-Type:text/html;charset=gbk
Set-Cookie:BAIDUID=A5B6C72D68CF639CE8896FD79A03FBD8:FG=1;expires=Wed,04Jul-42 00:10:47 GMT;path=/;domain=.baidu.com
Via:1.0 localhost(squid/3.0 STABLE18)
第一行是状态行,指定了协议版本号,通常服务器需要使用和客户端相同的版本;200 OK
是状态码和状态信息,常见的如下:
状态类型 | 状态码和状态信息 | 含义 |
---|---|---|
1xx 信息 | 100 Continue | 服务器收到了客户端的请求行和头部信息,告诉客户端请继续发送数据部分。客户端通常要先发送 Expect: 100-continue 头部字段告诉服务器自己还有数据要发送 |
2xx 成功 | 200 OK | 请求成功 |
3xx 重定向 | 301 Moved Permanently | 资源被转移了,请求将被重定向 |
302 Found | 通知客户端资源能在其他地方找到,但需要使用 GET 方法来获得它 | |
304 Not Modified | 表示被申请的资源没有更新,和之前获得的相同 | |
307 Temporary Redirect | 通知客户端资源能在其他地方找到,可以使用和原始请求相同的请求方法来访问目标资源 | |
4xx 客户端错误 | 400 Bad Request | 通用客户请求错误 |
401 Unauthorized | 请求需要认证信息 | |
403 Forbidden | 访问被服务器禁止,通常是由于客户端没有权限访问新资源 | |
404 Not Found | 资源没找到 | |
407 Proxy Authentication Required | 客户端需要先获得代理服务器的认证 | |
5xx 服务器错误 | 500 Internal Server Error | 通用服务器错误 |
503 Service Unavailable | 暂时无法访问服务器 |
第 2 ~ 7 行是 HTTP 应答的头部字段,其表示方法与请求相同:
Server:BWS/1.0
表示目标 Web 服务器程序的名字是 BWS(Baidu Web Server);Content-Length:8024
表示目标文档的长度为 8024 字节,这个值和 wget 输出的文档长度一致;Content-Type:text/html;charset=gbk
表示目标文档的 MIME 类型:
text
是主文档类型;html
是子文档类型;text/html
表示目标文档 index.html
是 text
类型中的 html
文档;charset
是 text
文档类型的一个参数,用于指定文档的字符编码。Set-Cookie:BAIDUID=A5B6C72D68CF639CE8896FD79A03FBD8:FG=1;expires=Wed,04-Jul-42 00:10:47 GMT;path=/;domain=. baidu.com
表示服务器传送一个 Cookie 给客户端:
BAIDUID
指定 Cookie 的名字;expires
指定 Cookie 的生存时间;domain
和 path
指定该 Cookie 生效的域名和路径。Via:1. 0 localhost(squid/3.0 STABLE18)
表示 HTTP 应答在返回过程中经历过的所有代理服务器的地址和名称,这个头部字段的功能类似于 IP 协议的记录路由功能。由于 HTTP 协议是一种无状态的协议,即每个请求之间没有任何上下文关系,如果服务器处理后续 HTTP 请求时需要用到前面的 HTTP 请求的相关信息,客户端必须重传这些信息,导致效率下降。
随着交互式 Web 应用程序兴起,HTTP 协议的这种无状态特性并不适用,因此需要使用额外的方法来保持 HTTP 连接状态,常见的方法就是 Cookie 。
Cookie 是服务器发送给客户端的特殊信息(通过 HTTP 应答的头部字段 Set-Cookie
),客户端每次向服务器发送请求的时候都需要带上这些信息,这样客户端便能够区分不同客户,实现用户行为的追踪。
在所有头部字段之后,HTTP 应答必须包含一个空行,与请求一样。空行之后是被请求文档 index.html 的内容,长度为 8024 字节。