【问题标题】:Correctly doing redirect_to :back in Ruby on Rails when referrer is not available当引用者不可用时,在 Ruby on Rails 中正确执行 redirect_to :back
【发布时间】:2010-10-20 18:37:33
【问题描述】:

redirect_to :back 有问题。是的,是推荐人。

我经常遇到异常

(ActionController::RedirectBackError) "没有在请求中设置HTTP_REFERER,所以redirect_to :back 无法成功调用。如果这是一个测试,请确保指定request.env[\"HTTP_REFERER\" ]。”

我意识到这是由于没有推荐人而导致的。有没有一种方法,例如,可以在每次访问最后一个页面时设置一个会话变量,并且当 HTTP_REFERER 不可用时,利用这个会话变量重定向到?

【问题讨论】:

  • 我在更新操作中遇到了同样的错误,这很奇怪,因为引用者不能为空(因为请求来自表单),但有些用户只是设法做到了这一点,而我却没有不知道怎么做。

标签: ruby-on-rails ruby http


【解决方案1】:

redirect_back_or_to (Rails 7+)

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

直接引用官方 Rails API 文档:

redirect_back_or_to(fallback_location, allow_other_host: true, **args)

如果可能,将浏览器重定向到发出请求的页面(引用者),否则重定向到提供的默认回退位置。

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

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

来源:

【讨论】:

    【解决方案2】:

    更新:Rails 5 添加了 redirect_back 方法 (https://github.com/rails/rails/pull/22506/),最好使用:

    redirect_back fallback_location: answer_path(answer), flash: { error: I18n.t('m.errors')}
    

    对于低于 5.0 的 rails 仍然可以使用下面的旧方式:

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

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

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

    redirect_back_or_default answer_path(answer), flash: { error: I18n.t('m.errors')}
    

    【讨论】:

      【解决方案3】:

      核心功能

      redirect_back 是 Rails 5+ 的核心功能,在 ActionController::Redirecting 模块中可用,该模块已包含在ApplicationController::Base 中。

      弃用警告:redirect_to :back 已弃用,将从 Rails 5.1 中删除。请使用redirect_back(fallback_location: fallback_location),其中fallback_location 表示请求没有HTTP 引用信息时要使用的位置。

      编辑:source

      【讨论】:

      • 请链接到源代码
      • @Chrisbloom7 这是我在使用redirect_to :back 运行 Rails 5.0.0beta3 时收到的警告消息。
      【解决方案4】:

      有会话而没有有推荐人是不太可能的。

      没有设置推荐人的情况并不少见,我通常会挽救这种期望:

      def some_method
        redirect_to :back
      rescue ActionController::RedirectBackError
        redirect_to root_path
      end
      

      如果您经常这样做(我认为这是个坏主意),您可以使用 Maran 建议的其他方法来包装它。

      顺便说一句,我认为这是一个坏主意,因为这会使用户流程模棱两可。只有在登录的情况下这是明智的。

      更新:正如几个人在 Rails 5 中指出的 no longer works。 相反,使用redirect_back,此方法还支持回退。那么代码就变成了:

      def some_method
        redirect_back fallback_location: root_path
      end
      

      【讨论】:

      • 我怀疑我会改成使用rescue_from。
      • @BobAman IMO 如果控制器有多个redirect_to :back,我们可以使用rescue_from
      • 不适用于 rails 5,ActionController::RedirectBackError 未定义...什么解决方案?
      • 改用这个:redirect_to (request.referrer || root_url)
      【解决方案5】:

      最近,我遇到了同样的问题,我必须重定向 :back 或重定向到特定页面。经过很多解决方案后,我终于发现这个很简单,似乎可以解决问题:

      
      if request.env["HTTP_REFERER"].present?
          redirect_to :back
      else
          redirect_to 'specific/page'
      end
      

      如果您想使用session 详细信息,请在代码的 else 部分进行。

      【讨论】:

        【解决方案6】:

        这是我的小 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
        

        如果 http_refferrer 为空,你可以传递一个可选的 url 去其他地方。

        【讨论】:

          【解决方案7】:

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

            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
          

          你可以像这样使用它:

          redirect_back_or_default(some_path, :notice => 'Hello from redirect', :status => 301)
          

          【讨论】:

            【解决方案8】:
            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
            

            试试看! (感谢Authlogic 插件)

            【讨论】:

            • 这是一个很好的解决方案,但我敦促任何使用它的人记住,如果他或她使用多个选项卡浏览,它可能会以一种让用户极度困惑的方式“破坏”你的应用程序。
            • +1 用于回答问题而不是批评设计方法。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-21
            • 1970-01-01
            • 1970-01-01
            • 2010-10-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多