当referrer不可用时,正确地执行redirect_to:返回Ruby on Rails

use*_*050 91 ruby ruby-on-rails http

我遇到了问题redirect_to :back.是的,这是推荐人.

我经常得到例外

(ActionController :: RedirectBackError)"在此操作的请求中未设置HTTP_REFERER,因此无法成功调用redirect_to:back.如果这是测试,请确保指定request.env [\"HTTP_REFERER \"]."

我意识到这是推荐人无法使用的结果.有没有办法,例如,可以在访问的最后一页访问每次访问时设置一个会话变量,当HTTP_REFERER不可用时,利用此会话变量重定向到?

har*_*arm 142

这是不可能的,你这样做有一个会议,并没有有引用.

引用者没有设置的情况并不罕见,我通常会拯救这种期望:

def some_method
  redirect_to :back
rescue ActionController::RedirectBackError
  redirect_to root_path
end
Run Code Online (Sandbox Code Playgroud)

如果你经常这样做(我认为这是一个坏主意)你可以用Maran建议的其他方法包装它.

BTW我认为这是一个坏主意,因为这会使用户流模糊不清.只有在登录的情况下这才是明智的.

更新:有几个人指出这不再适用于Rails 5.相反,使用redirect_back,这种方法也支持回退.代码然后变成:

def some_method
  redirect_back fallback_location: root_path
end
Run Code Online (Sandbox Code Playgroud)

  • +1因为这就是我要说的 (6认同)
  • 我怀疑我会改变它来改为使用rescue_from. (4认同)

Mir*_*rko 38

这是我的小redirect_to_back方法:

  def redirect_to_back(default = root_url)
    if request.env["HTTP_REFERER"].present? and request.env["HTTP_REFERER"] != request.env["REQUEST_URI"]
      redirect_to :back
    else
      redirect_to default
    end
  end
Run Code Online (Sandbox Code Playgroud)

如果http_refferrer为空,您可以传递可选的URL以转到其他位置.


Mar*_*ran 37

def store_location
  session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
  session[:return_to] = nil
end
Run Code Online (Sandbox Code Playgroud)

试试吧!(感谢Authlogic插件)

  • 这是一个很好的解决方案,但我敦促任何使用它的人都要记住,如果用户使用多个标签浏览您的应用,它可能会以非常混乱的方式"中断". (22认同)
  • +1用于回答问题而不是批评设计方法. (3认同)

Cyr*_*ris 29

核心功能

redirect_back是Rails 5+的核心功能,它已在ActionController::Redirecting已包含的模块中提供ApplicationController::Base.

DEPRECATION WARNING:redirect_to :back已弃用,将从Rails 5.1中删除.如果请求没有HTTP引用信息,请使用redirect_back(fallback_location: fallback_location)where fallback_location表示要使用的位置.

编辑:来源


tro*_*oex 21

也许现在已经晚了,但我想分享我的方法,这也保留了选项:

  def redirect_back_or_default(default = root_path, *options)
    tag_options = {}
    options.first.each { |k,v| tag_options[k] = v } unless options.empty?
    redirect_to (request.referer.present? ? :back : default), tag_options
  end
Run Code Online (Sandbox Code Playgroud)

您可以像以下一样使用它:

redirect_back_or_default(some_path, :notice => 'Hello from redirect', :status => 301)
Run Code Online (Sandbox Code Playgroud)


小智 13

类似于@ troex的答案,将其添加到您的应用程序控制器

def redirect_back_or_default(default = root_path, options = {})
  redirect_to (request.referer.present? ? :back : default), options
end
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器中使用它

redirect_back_or_default answer_path(answer), flash: { error: I18n.t('m.errors')}
Run Code Online (Sandbox Code Playgroud)


Mar*_*n13 12

redirect_back_or_to(Rails 7+)

Rails 7 提供了一种新的惯用方式来重定向回或重定向到后备位置。

直接引用官方Rails API文档:

redirect_back_or_to(fallback_location, allow_other_host: true, **args)
Run Code Online (Sandbox Code Playgroud)

如果可能,将浏览器重定向到发出请求的页面(引荐来源网址),否则重定向到提供的默认后备位置。

Referrer 信息是从请求的 HTTP Referer (sic) 标头中提取的。这是一个可选标头,其在请求中的存在取决于浏览器安全设置和用户首选项。如果请求缺少此标头,则将使用fallback_location。

redirect_back_or_to({ action: "show", id: 5 })
redirect_back_or_to @post
redirect_back_or_to "http://www.rubyonrails.org"
redirect_back_or_to "/images/screenshot.jpg"
redirect_back_or_to posts_url
redirect_back_or_to proc { edit_post_url(@post) }
redirect_back_or_to '/', allow_other_host: false
Run Code Online (Sandbox Code Playgroud)

还值得一提的是,
Rails 5 方式redirect_back(fallback_location: '/things/stuff')
与新引入的方式具有完全相同的行为redirect_back_or_to('/things/stuff')

资料来源: