先废话几句。
目前,我正在写一个web框架(没办法,作为毕业设计),因此持续关注这个领域。在很多框架的介绍页面,我都看到了“RESTful Supported”字眼,之前一直被搞得云里雾里,网页也能这么麻烦?好在最近正在拜读《RESTful Web Services Cookbook》这本书,没想到这方面的细节还挺多,所以想尽可能通过一个系列的blog向大家介绍REST。
REST是由Roy Fielding在其博士论文中提出来的,简单地说,它是一种架构风格,或者说是对web应用开发的一种架构风格的约束。经常用servlet的开发这一定对doGet和doPost相当熟悉,这两个函数对应HTTP中的GET和POST方法。仅仅使用这两个方法,其实就能开发比较复杂的网站了。这就让我们潜意识中认为“开发web,是如此的随心所欲,只要实现get和post就万事大吉了”。那么如果我们按照REST开发web(称之为RESTful),正常情况下,能够改善可扩展性(scalability)和可维护性,不过与此同时,它也要求开发者对HTTP方法有更加深入的理解和认识。
在这篇post中,我会先向大家介绍最基本的HTTP方法,以及它们对应的安全性。参考了上文中提到的那本书,wiki,以及其他一些内容,应该构不成“Plagiarize”。当然对于有能力的读者,我还是强烈建议阅读下那篇paper。
好,开始正文。
按照RFC2616的排序,HTTP的方法包括:OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE。下面我们将按照这个顺序进行介绍。
名词解释
- 安全性:客户端可以发起请求,并知道它不会改变资源的状态。
- 幂等性:保证客户端重复发起某个请求的效果与一次请求的效果一致。
HTTP方法
OPTIONS
使用该方法来获取资源支持的HTTP方法列表,或者ping服务器。
- 请求:只有header没有body。
- 响应:默认只有header,但是也可以在body中添加内容,比如描述性文字
示例:
# 测试对应资源所支持的方法
OPTIONS /test-options HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 204 No Content
Allow: GET, POST, OPTIONS
# ping服务器
OPTIONS * HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 204 No Content
- 安全:是
- 幂等:是
显然,它就是一个纯粹的信息读取的操作,不改变资源的状态,同时保证幂等性。
GET
该方法用以获取资源的表述。
- 请求:只有header,没有body。
- 响应:对应请求URI的资源表述,通常带有body。响应header中的Content-Type,Content-Length,Content-Language,Last-Modified,ETag等应该和响应body的表述一致。
# 请求
GET /hello HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
Content-Length: 21
<hello>tester</hello>
- 安全:是
- 幂等:是
简单的资源信息读取,不对资源状态造成影响,保证幂等性。
HEAD
使用该方法可以获取与GET响应相同的header,但是响应中没有任何body。
- 请求:只有header,没有body。
- 响应:只有header,没有body。服务器不能添加body。
# 请求
GET /hello HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
Content-Length: 21
- 安全:是
- 幂等:是
简单的资源信息读取,不对资源状态造成影响,保证幂等性。
POST
让资源在服务器上执行一系列操作,如创建新资源、更新资源、变更资源等。
- 请求:一个资源的表述。
- 响应:一个资源的表述,或是一个重定向指令。如果body中存在表述,则其URI和请求URI不一致,包含一个带有改资源URI的Content-Location头。
# 执行动作的请求
POST /prompt/delete HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 204 No Content
# 创建资源的请求
POST /stu/bob HTTP/1.1
Host: localhost
Content-Type: application/xml
<student>
<name>Bob</name>
<age>22</age>
</student>
# 响应
HTTP/1.1 201 Created
Location: http://localhost/stu/bob
Content-Location: http://localhost/stu/bob
Content-Type: application/xml
<student>
<name>Bob</name>
<age>22</age>
</student>
# 修改资源的请求
POST /stu/bob/modify HTTP/1.1
Host: localhost
Content-Type: application/json
{
"Name": "Bob",
"Age": 24
}
# 响应
HTTP/1.1 303 See Other
Location: http://localhost/stu/bob
Content-Type: application/xml
<student>
<name>Bob</name>
<age>24</age>
</student>
- 安全:否
- 幂等:否
是一个资源写的操作,改变了资源的状态,同事HTTP标准设定POST方法为非幂等,也就是说不需要在实现服务端响应方法的时候,我们不需要保证幂等,这也就避免了很多冗余信息(我们会在DELETE中看到)。
PUT
完整地更新或替换一个现有资源,也可以用客户端制定的URI来创建一个新资源。
- 请求:一个资源的表述。请求的body可以与客户端后续收到的GET请求一样,当然,也可以不一样。在某些情况下,服务器也可要求客户端只提供资源的可变部分。
- 响应:更新的状态。可在响应中包含被更新资源的完整表述,但是客户端不能假设响应中包含完整状态,除非响应有一个Content-Location头。如果服务器没有包含这个头,客户端必须提交一个无条件GET请求来获取更新后的表述,带有Last-Modified和/或ETag头。
# 更新资源的请求
PUT /stu/bob HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 204 No Content
# 创建资源的请求
PUT /stu/alice HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 201 Created
Location: http://localhost/stu/alice
Content-Length: 0
- 安全:否
- 幂等:是
和POST方法一样,PUT方法也改变了资源的状态,所以是非安全的。但是有一点和POST不同,它是幂等的,这是为什么呢?想想setter函数吧,重复调用,只要参数是一样的,表述就是不变的。
DELETE
使用该方法来删除资源。对于客户端而言,资源在成功响应后,就不复存在了。
- 请求:只有header,没有body。
- 响应:成功或失败。body中可以包含操作的状态。
# 请求
DELETE /doc/old.txt HTTP/1.1
Host: localhost
# 响应
HTTP/1.1 204 No Content
- 安全:否
- 幂等:是
和POST方法一样,DELETE方法也改变了资源的状态,所以是非安全的。但是有一点和POST不同,它是幂等的,也就是说,就算是服务器在前一个请求中已经删除了资源,它也必须返回200.这就意味着,我们在实现服务端的该方法是,需要跟踪已经删除的资源,否则就会返回404的。
TRACE
回显服务器接收到的header。支持该方法的服务器可能存在XST安全隐患。
- 安全:
- 幂等:
- 请求:header与body。
- 响应:body中包含整个请求消息。
# 请求
TRACE /trace HTTP/1.1
Host: localhost
Accept: text/html
# 响应
HTTP/1.1 200 OK
Content-Type: message/http
# 空行
TRACE /trace HTTP/1.1
Host: localhost
Accept: text/html
页面排版读起来有点累啊....
昨天刚修改的主题,reset部分把浏览器中的默认样式给清除了,然后昨晚紧急修复,发现七牛的缓存失效了。。。
Gravatar服务不能用?
试试gravatar.duoshuo.com吧~
对了~ 评论可以试试Disqus, 自动发送邮件提醒被评论的用户.
你值得拥有~
gravatar没弄明白怎么和typecho一起用,暂时需求不大。邮件提醒这个功能原来有,只是我没有开postfix。。。