之前说过,服务器对于方法的处理,是没有强制的规范的。这句话说得并不全对。其实每个HTTP方法,都是有一些HTTP协议要求的。比如说GET方 法请求的资源,浏览器端一般都会有缓存,下次请求的时候可能从缓存中去取就够了,服务器不用再重复发送相同的资源了;但是服务器如果将获取资源的接口的方 法定义为POST,那么浏览器端就不会再对资源进行缓存了,即使每次取到的都是同样地内容,都会请求服务器重新发送一遍。所以说,将请求资源的接口的方法 定义为POST而不是GET,就是一种不合理的设计。再比如,GET方法的请求消息是不能定义消息体的,HEAD方法的请求其响应消息是不包含消息体的,这些都是HTTP协议对于HTTP方法的约束。
HTTP请求:路径方法和路径的组合构成WEB API的入口,路径也是很关键的。路径的基本格式一般是:
basic-path[?query-string]其中[]中的内容表示可选的。在上例中,basic-path就是/simple.html,但不包含query-string的内容。basic-path形式很像UNIX中绝对路径的样式,要以/打头。单独的/表示一种路径,/a、/a/b、/a/b/c都是合理的路径表示。不推荐使用/a/、/a/b/、/a/b/c/这样/后面不跟任何其他内容的形式(/除外)。优秀的API设计者会利用不同的路径层级来合理地组织资源。
问号后面的部分就是query-string。它的格式是任意的,只要客户端和服务器约定好一定的形式即可。这个部分一般是请求参数的附加。之前说 过,GET方法是不包含请求体的,所以GET方法的HTTP请求想要附加参数只能使用这种方式。当然其他方法也是可以使用这种方式附加参数,只要服务器同 意就可以了。query-string的格式任意,但在客户端和服务器之间也有预先定好的约定,即键值对的形式。query-string可以表示成一系 列键值对的集合,用以下方式表示:
k1=v1&k2=v2&k3=&k4在这里,&分隔不同的键值对,=表示键和值得关系。可以看到一共有四个键值对关系,它们是:
一般来说,键值对要写成k=v的形式,但是k=和仅仅一个k都是允许的,前者表示键k的值是空字符串,后者表示键k被定义了,但是其值是什么并不关心。从上面的例子中发现,在query-string中&和=被用于特殊的用途了,我们不能再在其中从容地使用这两个符号了。如果我们要在值中包含这两个符号,那咋办呢?方法就是,编码。
在实际的HTTP请求中,对于如下的键值关系
k1: &k2: =具体的query-string要写成:
k1=%26&k2=%3D这是因为在ASCII编码中,&的16进制表示是26,=的16进制表示是3D。对于需要的编码,就要表示成其实际编码的16进制表示,每个字节都用一个%XX三个字符进行表示。这样,%本身也就要进行编码了,它的编码是%25。除了这些控制字符的编码,还可以进行中文等非英语语言的编码。
HTTP请求头HTTP请求头格式与之前所说的消息头格式没什么两样,就是以冒号分隔的键值对。HTTP请求头中,既包含预定义的头(如Content- Type、Content-Length等),也支持自定义头。原本打算多列出几个常见的请求头的,但限于精力,不打算这样做了。我只说说我最常用的 Content-Type头吧。Content-Type头,既可用于请求消息,也可用于响应消息,是规定请求正文内容格式的头部。例如利用这个头部,我们可以规定正文的格式为纯文本格式、表单格式、XML格式、JSON格式、图像格式等。例如Content-Type: application/json就表示JSON文本格式。
HTTP响应HTTP响应消息的基本格式也是一样的,包含三个部分:
响应头部和响应正文我觉得不需要再多说了。响应行的基本格式是:
版本号 状态码 状态文本例如下面的响应行:
HTTP/1.1 200 OK其对应关系为:
HTTP状态码主要表示应答的状态。状态码是由3个数字表示,其中第一个数字表示一个大状态,后面两个数字表示该大状态的一个子状态。200就表示操作成功,还有其他常见的如404表示对象未找到,500表示服务器错误,403表示不能浏览目录等等。
状态码一共分为五个大状态,它们是:
HTTP协议示例:接下来的所有示例中,我们将代码都写成前面的一行一行的模式,但略去. 这时只要记住每行的结尾都暗含一个CRLF控制就可以了。例如:
GET /simple.html?bg=white HTTP/1.1Accept: text/html Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 Host: localhost:8080 Connection: Keep-AliveGET请求没有请求正文,但可以包含query-string.
POST请求可以包含请求正文,例如下面带JSON格式正文的POST请求:
POST /test/demo_form.asp HTTP/1.1Host: w3schools.comContent-Type: application/json Content-Length: 38{"name1": "value1", "name2": "value2"}一个返回404错误的响应示例:
HTTP/1.1 404 Not Found Date: Mon, 06 Mar 2006 09:03:14 GMT Server: Apache/2.0.55 (Unix) PHP/5.0.5 Content-Length: 291 Keep-Alive: timeout=15, max=100 Connection: Keep-Alive Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html> <head> <title>404 Not Found</title> </head> <body> <h1>Not Found</h1> <p>The requested URL /notexist was not found on this server.</p> <hr> <address>Apache/2.0.55 (Unix) PHP/5.0.5 Server at localhost Port 8080</address> </body> </html>