应答3-重定向(redirect_to)

一个HTTP redirect 被从服务端发送给客户端,以应答一个请求。它会说,“我不能处
理这个请求,但这儿有些人能处理”。Redirect 应答包括一个URL,它是客户端应该试着下
次发送同样的状态信息给这个redirect,而不管它是持久的(状态码301)还是临时的(状态码
307)。有时,当web 页面被重新改编时,redirect 会被使用;访问旧位置页面的客户端将被
引到页面的新位置。
Redirect 背后由web 浏览器进行处理。通常,你只知道重定向稍微有些延迟,并且你看
到的页面的URL 将被从你的请求修改。最后一点很重要—直到浏览器关注它,来自于服务端
的redirect 动作与最终你手工地输入目的URL 是一样的。
当写well-behaved Web 应用程序时,关掉redirect 是很重要的。
让我们看个简单的博客应用程序,它支持评论,我们的应用程序应该重新显示文章,新
的评论在尾部。下面是代码。
class BlogController
def display
@article = Article.find(params[:id])
end
def add_comment
@article = Article.find(params[:id])
comment = Comment.new(params[:comment])
@article.comments << comment
if @article.save
flash[:note] = "Thank you for your valuable comment"
else
flash[:note] = "We threw your worthless comment away"
end
# DON'T DO THIS
render(:action => 'display')
end
end
这儿很明显故意地在一个评论之后显示文章。要做到这点,开始在add_comment()方法
结束时调用render(:action=>’display’)。这会提交显示“视图”,显示最终用户更新的
文章。但从浏览器角度想想。它发送了一个尾部为blog/add_comment 的URL,并且取回了索
引列表。直到浏览器被连接,当前URL 的尾部还是blog/add_comment。这意味着如果用户点
击刷新(或许是想看看否有其它人的评论),add_commandt URL 将被再次发送给应用程序。用
户的目的是刷新显示,但应用程序看到了一个被添加到其它comment 上的请求。
在这些情况下,正确的方式是在index 列表中显示添加的评论,并将其重定向给浏览器
的display“动作”。我使用Rails 的redirect_to()方法来做。如果用户随后刷新浏览器,
它会简单地调用display“动作”,并不会添加其它的评论。
def add_comment
@article = Article.find(params[:id])
comment = Comment.new(params[:comment])
@article.comments << comment
if @article.save
flash[:note] = "Thank you for your valuable comment"
else
flash[:note] = "We threw your worthless comment away"
end
redirect_to(:action => 'display')
end
Rails 也有一个简单但强大的重定向机制。它可以重定向到给出的“控制器”(传递参数)
内的“动作”,或重定向到当前服务端的一个URL,或重定向到一个任意的URL,让我们依次
看看这三种形式。
1、redirect_to 重定向一个“动作”
redirect_to(options...) 基于选项哈希表内的值发关一个临时重定向给浏览器。目标
URL 使用url_for()生成,所以redirect_to()格式有Rails“路由器”代码在背后支持。可
查阅280 页16.3 节。
2、redirect_to 重定向到应用程序内的一个固定路径。
redirect_to(path) 重定向到给出的路径。用前导“/”开头的路径,相对于协议,主机,
当前请求的端口。这个方法不会URL 上完成任何的重写工作,所以它不应该被用于创建,期
望连接到应用程序内一个“动作”的路径。
def save
order = Order.new(params[:order])
if order.save
redirect_to :action => "display"
else
session[:error_count] ||= 0
session[:error_count] += 1
if session[:error_count] < 4
flash[:notice] = "Please try again"
else
# Give up -- user is clearly struggling
redirect_to("/help/order_entry.html")
end
end
end
3、redirect_to 重定向到一个有绝对路径的URL。
redirect_to(url) 重定向到一个给定的完整的URL,它必须用一个协议名字来开头(如
http://)。
def portal_link
link = Links.find(params[:id])
redirect_to(link.url)
end
缺省情况下,所有重定向都是临时性的(它们只影响到当前请求)。当重定向一个URL 时,
你或许是想得到永续的重定向。在这种情况下,设置“应答头”内的状态。
headers["Status"] = "301 Moved Permanently"
redirect_to("http://my.new.home")
因为重定向方法发送应答给浏览器,同样的规则也适用于提交方法—你可发一个请求。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值