原文地址:HTTP: Response Code
在上一篇文章中,我们总结说HTTP管理客户端和服务端之间的交互,并且解释HTTP头部的概念。在随后的系列文章中我们将讨论更多关于以下方面的信息:对交互和性能的影响。现在,让我们看看同样重要的并且与交互相关的内容:HTTP响应码。
街上漫步
早上,我走路去一个咖啡馆看书。出乎我的意料,当我到达那里的时候,咖啡馆关门了。门上有一条留言说道,本周要举行一个节日,本咖啡馆要在餐车上提供临时服务,在307号大街,在河旁边。我又走到那里,终于享用到了我的咖啡。
接下来我决定“今天是一个逛书店的好日子--我要去我最喜欢的书店。”当我到那儿的时候,我发现这个书店也关门了,但是也不算太糟:门上有一条信息说因为书店需要更大的空间,所以他们已经搬迁到了301大街。“Cool,”我自言自语道,“还不算太远--我要去那儿找他们。”当我到那儿的时候,店员认出了我,用了200种方式欢迎我。好吧,我在夸大其词,但是你理解了我的意思,不是吗?
在我回家的路上,在410大街,那里有一个商店,窗户上布满了灰尘。来自店主的一份通知说他申请了破产不得不关门,而且要永远的离开了。当我走到500号大街的街尾时,我更加的吃惊:一个四层楼的建筑完全倒塌了。我不确定那里到底发生了什么。
不管怎么说,这一天过得还不错。我想我应该使这一天过得个更完美,所以我决定写一写作为客户端发送请求的响应,服务器发送给客户端的HTTP codes。
HTTP响应语法和状态行
在上一篇文章中,我们谈及了客户端发送的请求语法的第一行(包含使用的方法)。这一次我们将只要关注来自服务器响应信息的第一行,以及这一行中出现的不同代码的含义。注意这两种类型的消息--请求和响应--非常相似。正如HTTP/1.1中规定的那样:
一个HTTP消息可以是客户端发送给服务器的请求,也可以是服务器发送给客户端的响应。在语法结构上,两种类型的消息只在开头的那一行上存在不同--要么是请求行(对于请求来说),要么是状态行(对于响应来说)--以及在用于确定消息体长度的算法中。
响应消息的第一行叫做状态行。这一行以HTTP协议的版本开头,接着是一个空格,然后是3个数字组成的状态码,再一个空格,最后是一个解释的句子。下面是一个例子:
HTTP/1.1 200 OK
服务器和HTTP响应状态码
200, OK -- everything is fine
每一次用户想要访问Opera的主页时,客户端会向地址http://www.opera.com发送如下请求消息:
GET / HTTP/1.1
Host: www.opera.com
Accept-Language: fr
User-Agent: BrowseAndDream/1.0
服务器会分析来自客户端的消息,并且根据URI和头部信息做出相应的应答。正如之前文章中说的那样,所有这些都是关于使双方(客户端和服务器)以最大的能力进行交互。
服务器分析完毕并理解后,就会对这个请求做出响应,发送一个以200 OK开头的消息,表示一切顺利,那么这次请求就算是成功了。这个响应消息会包含一些HTTP响应头部信息和这个页面的内容。至于是什么内容取决于客户端发送请求的HTTP头部信息,这个没有绝对的答案。正如任何谈判一样,这是为双方找到最好让步的对话。下面是对于我们上面请求的响应:
HTTP/1.1 200 OK
Date: Fri, 24 Aug 2012, 13:56:44 GMT
307, moved temporarily elsewhere
服务器可以给客户端响应一条消息指出内容已临时迁移到了新位置。当你想把客户端重定向到一个特定页面时,这非常有用。比如,想想一下有一个网址提供台北的天气预报,但是最近将会出现强台风。那么在强台风过去之前,给用户详细介绍强台风的信息将是一个好主意。请求可能看起来是这个样子:
GET /taiwan/weather/today HTTP/1.1
Host: meteo.example.org
服务器可能想给客户端回应“这里有一个页面可以给你提供关于台北当前危机的详细信息。”响应消息看起来可能是下面的样子:
HTTP/1.1 307 Temporary Redirect
Date: Fri, 24 Aug 2012, 13:56:44 GMT
Location: http://meteo.example.org/taiwan/weather/crisis
通常情况下,浏览器会自动跳转到Location字段指定的新地址。重定向也可以是互联网上的另一个域名。一旦危机过去,重定向将会从服务器上移除。客户端不应该将重定向作为最终确定的东西记录下来。这对于书签和浏览历史来说非常重要。通过编程让客户端以有意义的方式管理这些重定向是完全有可能的。
尽管在大多数浏览器中这些重定向对用户来说是不可见的,但是创建一个带有指向新的地址的链接的简短消息体,让用户通过点击跳转到新的地址也是有可能的。
301, address changed permanently
当在网站上管理信息时,有时候真的需要告诉客户端(和他的用户)网页的地址已经永久地改变了。在一个公司中,有时候会通过合并或者改变优先级对事业部门进行重组。假设在一个技术公司,机电部门已经被电子部完全吸收了。客户端发送了一个请求:
GET /section/electromech/about HTTP/1.1
Host: inc.example.com
这个请求可能会被重定向:
HTTP/1.1 301 Moved Permanently
Date: Fri, 24 Aug 2012, 13:56:44 GMT
Location: http://inc.example.com/section/electronic/about
这个状态码与我们之前介绍的307状态码之间的不同是这次的重定向是永久的,服务器会给客户端发送一个清除指令告诉客户端,如果客户端将旧的URI保存为了书签,那么就要将书签中旧的URI更改为新的URI。这个过程可以自动完成也可以经过用户确认后完成。
将旧的URI重定向到新的还有两个直接的好处。第一,通过维护信息以及显示出你对你管理的信息的关心,你与你的用户之间建立了信任。第二个好处来自于资源的稳定性。以维护链接而著称的网站在长期内更有可能让其他网站链接到他们,从而改善他的搜索引擎的能力。
401, this is the end -- my only friend, the end
有时候,网站需要告诉客户端保存在这个URI下的信息永远的丢失了。有充分的理由需要这么做。我们都知道酷的URI一般不会坏掉,401 Gone是一个合适的让其“坏掉”的方法。更确切的说,这是一种告诉用户在这个URI下先前可用的内容被故意删除的方法。服务器通知客户端不应该记住与该资源对应的URI。在有书签或历史日志的系统中,这是一种告诉客户端或用户可以放心删除的方法。想像在社交网络中,访问一个特定用户的页面:
GET /people/jeanpaulsartres HTTP/1.1
Host: socialnetwork.example.com
这个用户再成为社交网络的一部分了,并且决定关闭他的账户。在服务器端,你可能想警告访问这个URI的用户,因为他们可能把这个URI添加到他们的书签或历史记录中了:
HTTP/1.1 410 Gone
500, I have a bad feeling about this
有时候服务器会由于未知原因而不能对请求做出响应。HTTP完全不涉及网站的工作方式,例如数据如何存储在数据库中或者服务端代码如何检索和操作数据。服务器可能将请求分发给了内部的某个软件但是并没有收到一个合适的回应。所以服务器会通知客户端和用户有未知的错误出现了:
HTTP/1.1 500 Internal Server Error
在web服务器中实现响应状态行
当设计一个管理内容的系统时,将资源分为不同的层次以及给他们分配URI是必要的。当给客户端的请求回应合适的信息时这很有帮助。给软件或个人提供内容是在时间的结构上精心设计的。信息是不断地演变和变更的。在事先就考虑到这一点可以使系统更易扩展。给出所有服务器响应的代码方案并不是本文的目的,但下面的例子至少能给你一个起点,尽管在涉及上千个URI的操作中会他们可能并不灵活。
使用Apache重定向
如果我们想把http://inc.example.com/section/electromech/about重定向到http://inc.example.com/section/electronic/about,一个解决方案就是在我们的站点的根目录下放一个.htaccess文件,文件的内容是:
RewriteEngine On
RewriteBase /
RewriteRule ^/section/electromech/about /section/electronic/about [L,R=301]
Note:当然还有其他的方法也可以处理这种情况:通过httpd.conf,通过数据库,通过脚本等等。使用哪种方法取决于你的系统的构建方式。
使用nginx重定向
Nginx是另外一个经常使用的服务器,它主要用于内容分发网络。上面的例子使用nginx重写的话会是下面的样子:
server {
listen: 80;
server_name inc.example.com;
rewrite ^/section/electromech/about http://inc.example.com/section/electtonic/about permanent;
}
HTTP codes, we are family
上面我们讨论的仅仅是HTTP状态码中的几个,还有很多其他的状态码。其中有一些非常的著名,比如404 Not Found,当然也有一些十分的隐蔽,不经常出现。无论如何,状态码的第一个数字表明了这个状态码所属的系列:
1xx(信息):请求已经收到,过程继续。
2xx(成功):该行为已经成功地收到,理解和允许。
3xx(重定向):需要采取进一步的行动才能完成请求。
4xx(客户端错误):请求包含错误的语法或者无法被满足。
5xx(服务器错误):服务器无法满足明显有效的请求。
总结
现在我们要结束HTTP状态码的学习了。我鼓励你探索每一个HTTP码,并熟悉他们的作用。有些对缓存和HTTP消息的资源有效载荷有特殊的影响。我们将在下一次讨论缓存。
你需要记住什么
服务器在给响应中给客户端发送HTTP状态码以提供快捷消息。
HTTP状态码对缓存有影响,并且在客户端一侧处理URI。
有不同系列的HTTP状态码。