respond_to和redirect_to的区别

class AirportsController < ApplicationController
def index
    @airports = Airport.find :all
    respond_to do |format|
      format.html # do nothing, allow Rails to render index.rhtml
      format.js # do nothing, allow Rails to render index.rjs
      format.xml { render :xml => @airports.to_xml }
    end
end
end

我们以index方法为例,其它方法的实现大同小异。第一行代码很容易理解,获取所有的机场信息,但是接下来的代码就比较费解了,而这也正是REST on Rails的关键所在,那个respond_to是做什么的呢?

上面的代码是说,如果客户端需要从这个action得到一个HTML的响应,就渲染html模板,但是如果客户端需要XML,那么就返回XML格式的数据。(rails根据客户端所提交请求中HTTP accept header来决定响应的类型)

  上面的一段话是我文档当中的解释(当然只是大意,翻译的并不准确,因为还涉及到一些上下文的关联),在文档当中还有这样的一段话,大意是说:如果在应用程序当中不需要web-service的支持,那么就可以用redirect_to将请求重定向到一个action,而如果需要web-service的支持,就需要使用respond_to。不知道我这样的理解是否正确?


我们知道,在HTTP协议中,客户端会在他们的HTTP首部包含一些元信息(meta-information),这些元信息按照“字段:值”的方式来组织,HTTP协议预定义了很多标准字段,其中的一个字段就是“Accept-type“,它代表发送请求的客户端能够支持或者说理解的资源表示类型,如果没有为这个键指定值,服务端会认为客户端能够理解标准的HTML文档,当然,客户端可以为这个字段指定任意的符合MIME规范的类型值,假设客户端设置这个字段为”Accept-Type: text/xml“,则服务端必须返回资源的XML表示。

所以respond_to事实上就是根据HTTP首部的Accept-Type字段来决定向客户端返回那种类型的资源表示,如果不使用respond_to,我们的实现可能会是这个样子:


class AirportsController < ApplicationController

# Pretend that Rails will call our index action,
# and will pass in the value of the Accept-Type header
def index(client_format)
    @airports = Airport.find :all

    if client_format == “text/html”
      # TO DO: render the default template

    elsif client_format == “application/javascript”
      # TO DO: return some javascript

    elsif client_format == “application/xml” || client_format == “text/xml”
      # TO DO: return some XML back the client

    # … more elsif statements here for each MIME type you want to support
    end
end
end

这很丑陋,不是吗?但它却相当直观,我想respond_to的作者可能最初也是这么写的,或者这段代码至少在他的脑海中闪现过,但立刻就被他否定了,因为它实在是太蹩脚了,所以他对这段代码进行了重整,于是有了respond_to。

respond_to do |format|
format.html # do nothing, allow Rails to render index.rhtml
format.js # do nothing, allow Rails to render index.rjs
format.xml { render :xml => @airports.to_xml }
end


但是Block内的代码看起来仍然比较古怪,事实上,如果我们理解了respond_to的设计思想,那么这段代码看起来就非常理所当然了。

respond_to基于这样的思想设计的,你不需要知道客户端的请求到底是那种类型,你只需要告诉Rails你准备支持那些类型的请求,Rails会自动帮你处理剩下的事情。

所以,这里我们告诉Rails,对于HTML和JS类型的请求,采用默认的实现,而对XML则使用我们在Block内提供的实现。


respond_to是服务器对客户端请求的响应,所有的响应方式都是在这里处理的。而redirect_to是响应方式之一,respond_to与redirect_to不是一个层次上的东西,所以saberma会问你是不是想问render和redirect_to的区别。

render是将响应内容直接反馈给客户,而
redirect_to相当于重定向,要求客户端再次重新发送请求,“新的请求地址就是redirect_to后面的参数了”

render的另外一个用法容易与redirect_to混淆,就是在controller内部重定向到一个新的action,这种处理方法保持了请求中的params,而redirect_to是一个全新的请求,丢弃了params


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值