HTTP协议详解
HTTP协议作为网络传输的基本协议,有着广泛的应用。HTTP协议的完整内容很多,但是其核心知识却又简单精炼。小伟哥建议初学者应该掌握其基本结构,并且能够举一反三。
HTTP协议:消息的分类HTTP消息(有的文章称之为报文)分为请求消息和响应消息两种基本分类。其中请求消息是客户端发送给服务器的用于请求服务和资源的消息,响应消息是服务器对请求消息的应答。一般来说,一个响应对应一个请求,不多也不少。
HTTP协议:特点HTTP协议被人总结为无连接、无状态的特点:
其中,头部用来指出HTTP消息的一些属性,它们有固定的格式;正文部分是传输的实际内容,它们的格式是任意的,通常用Content-Type头 来指定。首行在请求消息和响应消息中具体格式略有区别,它们表示的按理说应该是HTTP消息最基本的部分。不论是HTTP请求还是HTTP响应,首行都是 有的,否则会出现不可饶恕的解析错误;然而头部和正文是可选的,不过实际过程中,多多少少都要包含一些基本的头。
HTTP消息主要是基于ASCII编码的消息实体。主要的意思是指首行和头部都是以ASCII编码,而正文部分的编码就显得任意了。在实际的开发中,发送的文本消息时常会碰到乱码的问题。一种解决办法是,对于文本消息,约定以UTF-8格式进行编码和解码。知道的人也许知道,HTTP消息是基于TCP协议的上层应用协议。TCP协议是网络流协议的一种。抽象地讲,就是从一台主机一个字节一个字节有序地传输到另一台主机。对于HTTP协议来说,自然保持了这种有序性,即按照首行、头部、正文的顺序进行传输。首行和头部都是ASCII文本流,正文部分是字节流。一个特殊的控制结构CRLF用来控制每个部分的结束。CRLF是回车符和换行符的意思,它们是两个特殊的ASCII字符。CR是回车符(\r),在ASCII中的编码是13;LF是换行符(\n),在ASCII中的编码是10.
下面通过一个例子来解释CRLF在HTTP消息中的控制。
GET /simple.html HTTP/1.1<CRLF> ----- 首行 Accept: text/html<CRLF> --| Accept-Language: zh-cn<CRLF> | Accept-Encoding: gzip, deflate<CRLF> |-- 头部 User-Agent: Mozilla/4.0<CRLF> | Host: localhost:8080<CRLF> | Connection: Keep-Alive<CRLF> --| <CRLF> ----- 空白行表示头部的结束 ----- 接下来的内容是正文部分这是一个简单的HTTP请求消息。我在其中做了一些必要的删减,以便每个头足够短都能在一行中显示。记住首行和头部是ASCII流,正文部分是字节流,它们在消息实体中是连续的片段,并不像代码中所示那样有换行的结构。换句话说,原始的消息应该是如下形式:
GET /simple.html HTTP/1.1<CRLF>Accept: text/html <CRLF>Accept-Language: zh-cn<CRLF>Accept-Encoding: gzip, deflate<CRLF>User-Agent: Mozilla/4.0<CRLF>Host: localhost:8080<CRLF> Connection: Keep-Alive<CRLF><CRLF>回到之前有换行符的代码例子中去。将每个CRLF单独列为一行是便于观察组织。可以清楚地看到,第一行是首行,以CRLF标志其结束;接下来是头 部,含有多个消息头,每行定义一个消息头,以CRLF标志其结束;一个单独的CRLF(紧接着上一个CRLF)表示整个头部的结束,接下来是正文部分。在 这个示例中,正文部分为空。另外,可以看到每个消息头的格式都是一致的,即Key:Value的形式。其中Key表示消息头的键,Value表示消息头的值。
HTTP请求接下来具体讲讲HTTP的请求消息。诚心而论,光是写上面这么点内容就花费了我好久。每每想到写博客耗费的精力和时间,都会影响到我写博客的动力。
之前已经说过,HTTP请求消息也分为三个部分:
其中请求头部的格式我们已经见过。请求行的基本格式为:
方法 路径 版本例如下面的例子:
GET /simple.html HTTP/1.1就有对应关系:
请求行是HTTP请求消息的最基本要素。版本是用来声明HTTP消息的解析规则,不同的版本在某些地方的表现是不同的,这里不作过多拆解了。现在实 际应用中最新的HTTP协议版本就是HTTP/1.1。路径可以理解成该请求消息发往服务器的入口,一般来讲,同一个路径应该代表同一个资源实体。方法表 示对该资源实体进行的操作,例如上述的GET方法,其含义就是请求获取该资源的内容。这些都是通常的解释,但不是必然的要求。实际上,服务器会解析到方法 和路径,根据方法和路径做出自己相应的响应。这种响应的规则,可以遵循某些规范,也可以完全不考虑这些规范,是任意的。市面上已经存在一些约定俗成的规范 了,比如Restful。Restful是非常优秀的基于HTTP协议的WEB API设计理念,很值得讲,但在这里就不讲了。
HTTP请求:方法首先列出最常用的HTTP方法: