`
LiZn
  • 浏览: 9830 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

HTTP Developer’s Handbook 中文翻译 Chapter 5:第二节 HTTP请求方法

阅读更多

原文地址: HTTP Developer’s Handbook 中文翻译 Chapter 5:第二节 HTTP请求方法

 

Request method(请求方法)是HTTP请求最重要的属性之一。方法指明了Web客户端请求的大体意图。他们都有重要的作用,尽管许多方法都不常应用于实践。大多数情况下我只会讨论由HTTP/1.1定义的方法,如果有必要我将会提示其与之前版本的不同。

HTTP/1.1中定义了8种方法:GET, POST, PUT, DELETE, HEAD, TRACE, OPTIONS 和 CONNECT

我将介绍这8种方法是最新的也是大多Web客户端和服务器遵守的。出于兼容性的考虑,通常会适当地介绍之前版本中与HTTP/1.1版本同名的方法。另外,几乎所有的现代Web客户端与服务器都至少支持HTTP/1.0。

The GET Method

Web客户端最常用的方法就是GET。这是当你点击一个链接或者在浏览器地址栏中输入一个URL,你的浏览器应用的请求类型。一个GET请求从根本上讲是一个用来接收位于一个特定URL中的内容。这是HTTP中最简单也是最古老的请求,成为HTTP/0.9中唯一能用的方法。

查询字串(query string), 就是URL中位于?符号之后,#符号之前(如果#存在的话)的部分,由一个或多个名值对用&字符分隔而组成。因此,一个查询字串指定的3个变量就是以下这种格式:

1 var1=value1&var2=value2&var3=value3

HTML表单中,<form>标签有一个属性method,可能的值有get和post。当赋值为get时,每一个表单域的名字和值会被包含在URL中作为查询字符串,Web客户端会向form表单的action属性中指定的地址发起一个GET请求。

使用GET请求的URL允许用户将URL生成书签,或者生成一个链接,或者发送给朋友等等。例如你可以将Google搜索结果生成书签,这样你每次访问这个书签都可以得到最新的搜索结果。同样的,你也可以在你的个人网站上包含一个这样的链接供用户访问。

对于很多表单来说,POST方法是更合适的。例如,你不会希望用户能够使用一个书签来产生购物订单。你也不会希望敏感的数据出现在浏览器的地址栏中,因为那将会使数据暴露在不怀好意的人的眼中。当你考虑在表单中使用哪一种方法时,要知道GET方法有一些缺点。GET方法在数据参数的长度上有所限制,并且这些限制对于不同的Web客户端和服务器有可能是不同的,这取决于他们的实现。几乎所有的现代Web客户端和服务器,包括Apache服务器,都可以处理1024个字符长度的URL。然而规范警告要当心那些超过255个字符长度的URL。你要知道URL并不仅仅只是包含查询字符串,如果表单有太多的表单项将有可能超出Web客户端或服务器的处理能力。

一个GET请求通常不包含正文内容,也就没有实体头部。

The POST Method

POST方法可以说是HTTP协议最大的进步之一,可以说它推动了Web向真正的交互型应用开发平台的变革。

POST方法通常以提交表单数据的方式被浏览器所支持。如果一个HTML表单指定了POST方法,浏览器将会使用POST请求来提交表单中的数据。用上一节提到的HTTP请求采样,下面的例子会阐述用POST方法来代替GET方法的情况。

1 POST /search HTTP/1.1
2 Host: www.google.com
3 User-Agent: Mozilla/5.0 Galeon/1.2.5 (X11; Linux i686; U;) Gecko/20020606
4 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,
5         text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,
6         text/css,*/*;q=0.1
7 Accept-Language: en
8 Accept-Encoding: gzip, deflate, compress;q=0.9
9 Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
10 Keep-Alive: 300
11 Connection: keep-alive
12 Content-Type: application/x-www-form-urlencoded
13 Content-Length: 31
14  
15 hl=en&q=HTTP&btnG=Google+Search

值得注意的是这个HTTP请求包含了一些实体头部:

1 Content-Type: application/x-www-form-urlencoded
2 Content-Length: 31

以及正文内容:

1 hl=en&q=HTTP&btnG=Google+Search

同样要注意到请求行中不仅是改为指定了POST方法,资源位置也没有了查询字串。因为查询信息被置于请求的正文中了。

同URL中的查询字符串一样,POST方法中的数据也是由&字符分隔的名值对组成的。并且,Content-Type头部表明了特殊字符会被URL编码。关于URL编码,请查阅Chapter 9 “Formatting Specifications”(暂时未翻译)。

Web开发者盲目的使用POST方法提交HTML表单而不考虑这种选择的优缺点已经成为一种不幸的趋势。我建议在做出选择之前优先考虑所提交的数据的性质。

在使用Google搜索的例子中,搜索项全是由客户端发送的。使用GET方法时,搜索结果可以用一个URL来引用。例如,以下的链接将会展示一个对于关键字“HTTP”的Google搜索结果。

这是非常方便的,因为这允许你通过一个简单的链接就获得一个搜索结果。如果你是一个开发者,你可以让你的用户通过单击链接就能得到搜索结果,而不用先在搜索框中输入关键字再单击提交按钮。一般来讲GET方法更加方便,而POST方法更适合于一部分需要保密的数据。

如果有很多数据需要提交,GET是一个糟糕的选择,因为这有可能会导致URL长度超过Web代理的URL长度限制。另外,多数用户不会注意到URL,所以URL中的敏感信息是很危险的。倒不是因为数据传输中容易被截取,而是因为他在Web客户端上缺少保护。数据会被显示在浏览器的地址栏中,可能会被浏览器的历史记录存储,并且用户可能会将地址作为书签或者把地址发给朋友。因此,POST方法更适用于大数据量和敏感信息的发送。然而POST方法并没有对数据传输采取任何保护措施。关于一般的HTTP消息的传输保护,请参阅Chapter 17 ”Secure Sockets Layer”(暂未翻译)。

The PUT Method

PUT方法并不像GET或者POST方法那样常用。但是它在特定情况下非常有用因为它允许Web客户端上传内容并存储在Web服务器上。

PUT方法的语义同POST方法很像。然而,请求行中的资源位置则是指所要求的用来存储正文内容的位置而不是需要接收的资源位置。所有相关的实体头与POST方法是一样的。

如果PUT方法导致了一个资源被创建,Web服务器会返回一个标识为201 Created 的响应。如果资源已经存在,并且PUT方法修改了它,那么会返回200 OK或者204 No Content。

PUT方法很少被Web客户端实现。通常会误以为PUT方法是用来上传文件的。然而上传文件这一功能实际上是POST方法的加强版,定义在 RFC1867 “Form-based File Upload in HTML”中。如果你尝试在表单中使用PUT方法,你的浏览器很有可能会只是使用GE方法来代替它,因为浏览器并不明白你的意图。例如:

1 <form action="/" method="put">

这通常会导致一个GET方法的提交,那并不是你所期望的行为。<form>标签的method属性只接受get或者post值。对于文件上传,你可以使用POST方法和file类型的input标签。

The DELETE Method

HTTP提供了一个与PUT方法对应的DELETE方法。一个DELETE请求将需要从Web服务器删除的内容指定为请求行中的资源部分。

DELETE方法唯一有趣的地方在于当你接收了一个标识为200 OK的响应的时候,那并不意味着指定的资源已经被删除了。那仅仅说明服务器接收到了删除资源的命令。这一例外允许了出于安全考虑的人为的干预。

The HEAD Method

HEAD方法对于那些想要研究HTTP传输行为的人来说是一个非常有用的方法。除了不会收到请求资源的正文内容以外,HEAD方法被期望同GET方法的行为一致。因此HEAD方法就像是一个不会收到HTML内容的GET方法。

例如,用上一节提到的HTTP请求例子,用HEAD方法来替换GET方法,你可以得到如下响应:

1 HTTP/1.1 200 OK
2 Server: GWS/2.0
3 Date: Tue, 21 May 2002 12:34:56 GMT
4 Transfer-Encoding: chunked
5 Content-Encoding: gzip
6 Content-Type: text/html
7 Cache-control: private
8 Set-Cookie: PREF=ID=58c00...cXi3RhSE;
9             domain=.googl...14:07 GMT

这完全就是使用GET方法得到的响应,只是没有正文内容。这对于代码调试和研究HTTP协议行为是很有用的。因为通常正文内容占到响应的大部分,在对正文内容不感兴趣的时候,HEAD方法允许你出于方便和清楚地考虑干掉正文内容。

Note
HEAD is not perfectly dependable for returning the HTTP headers that would be included in a normal response to a GETrequest. The reason is that it is possible for the resource generating the response to take the request method into consideration. For cases where you can tolerate the extra data, a GET request is much more dependable.(我没有理解此NOTE的内容,因为感觉作者也没有清楚地表述使用HEAD方法收到的响应不完全可信的原因。有大牛知道的话请不吝赐教,谢谢)

The TRACE Method(跟踪方法)

TRACE方法是另外一个用于诊断的方法,它允许客户端对于位于客户端与服务器指点的代理了解的更多。每一个代理都会在向Web服务器的路由上转发TRACE请求,并且会把自己添加到Via头部后面。

 

TRACE请求示例

TRACE请求示例

 

The OPTIONS Method

有时你希望能够通过一个简单的请求就获悉Web服务器的能力,出于对此目的的考虑,HTTP提供了OPTIONS方法。

考虑以下向本地的Apache服务器发送的请求:

1 OPTIONS * HTTP/1.1
2 Host: 127.0.0.1

其中的*并不是指定的资源,但是它允许OPTIONS方法在不指定任何资源的情况下向服务器询问其能力。收到的响应会详细说明服务器提供服务的能力。

1 HTTP/1.1 200 OK
2 Date: Tue, 21 May 2002 12:34:56 GMT
3 Server: Apache/1.3.22 (Unix)  (Red-Hat/Linux) mod_python/2.7.8 Python/1.5.2
4         mod_ssl/2.8.5 OpenSSL/0.9.6b DAV/1.0.2 PHP/4.0.6 mod_perl/1.26
5         mod_throttle/3.1.2
6 Content-Length: 0
7 Allow: GET, HEAD, OPTIONS, TRACE
8 Connection: close

Allow头部说明了服务器支持 GET, HEAD, OPTIONS, TRACE 方法。你可能注意到了为什么没有POST方法。如果你在OPTIONS方法中指定某一个资源的话,将会看见完全不通过的响应。

1 OPTIONS / HTTP/1.1
2 Host: 127.0.0.1

现在Apache可以展示其他适用于此资源的方法了。

1 HTTP/1.1 200 OK
2 Date: Tue, 21 May 2002 12:34:56 GMT
3 Server: Apache/1.3.22 (Unix)  (Red-Hat/Linux) mod_python/2.7.8 Python/1.5.2
4         mod_ssl/2.8.5 OpenSSL/0.9.6b DAV/1.0.2 PHP/4.0.6 mod_perl/1.26
5         mod_throttle/3.1.2
6 Content-Length: 0
7 Allow: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, PATCH, PROPFIND,
8        PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, TRACE
9  
10 Connection: close

OPTIONS方法还可用于侦测代理服务器的能力。如果一个代理服务器收到一个Max-Forwards头的值为0的请求,该代理服务器必须自己响应这个请求。如果这是一个OPTIONS请求,就能够让代理服务器说明它的能力了。

The CONNECT Method

CONNECT方法用于代理服务器创建到目的服务器的隧道。即不是HTTP客户端而是代理服务器来发送CONNECT请求至目的服务器。

隧道(Tunnel)与代理不同,它不会干扰HTTP请求(例如检查Max-Forwards头或者修改Via头),也不会缓存任何传输内容。对于客户端和服务器来说,隧道是透明的。只要TCP连接仍然存在,隧道就保持已建立的状态。一旦目的服务器关闭了与客户端的连接,隧道也就关闭了。

CONNECT方法最常用于一个Web客户端必须通过代理使用SSL(Secure Socket Layer)或TLS(Transport Layer Security)来请求一些敏感的资源的情况。路由上的代理服务器会只是简单转发从客户端来的请求或者从目的服务器端来的响应而不做任何干扰

Note
CONNECT方法还另外被用于SSL加速器去建立至Web服务器的隧道。SSL加速器代替Web服务器来与Web客户端进行SSL协商以及其他必须的加密处理,因此就把Web服务器从这个职责中解放出来。然后加速器通过已经建立的隧道转发解释过的HTTP请求给Web服务器,所以服务器就可以像是与处理普通的HTTP请求一样来处理了。在大多数实现中,客户端不会感觉到这一过程。更多请参见Chapter 17。

 

本博客文章由LiZn创作或分享,以创作公用CC 姓名标示-非商业性-相同方式分享 3.0 Unported 授权条款共享。 
转载请注明 转自: HTTP Developer’s Handbook 中文翻译 Chapter 5:第二节 HTTP请求方法 

1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics