4

在 Rails 3 上,我试图从没有斜杠的 URL 重定向到有斜杠的规范 URL。

match "/test", :to => redirect("/test/")

但是,上面的路由匹配 /test 和 /test/ 导致重定向循环。

如何使其仅匹配没有斜线的版本?

4

5 回答 5

6

您可以在控制器级别强制重定向。

# File: app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  protected

  def force_trailing_slash
    redirect_to request.original_url + '/' unless request.original_url.match(/\/$/)
  end
end

# File: app/controllers/test_controller.rb
class TestController < ApplicationController

  before_filter :force_trailing_slash, only: 'test'  # The magic

  # GET /test/
  def test
    # ...
  end
end
于 2014-01-22T03:45:52.653 回答
3

我想做同样的事情来为博客提供一个规范的url,这行得通

  match 'post/:year/:title', :to => redirect {|env, params| "/post/#{params[:year]}/#{params[:title]}/" }, :constraints => lambda {|r| !r.original_fullpath.end_with?('/')}
  match 'post/:year/:title(/*file_path)' => 'posts#show', :as => :post, :format => false

然后我有另一个规则来处理帖子内的相对路径。顺序很重要,所以前者排在第一位,通用排在第二位。

于 2012-09-11T06:36:53.903 回答
2

ActionDispatch 中有一个名为的选项,trailing_slash您可以使用它来强制在 URL 末尾添加斜杠。我不确定它是否可以在路由定义中使用。

def tes_trailing_slsh
  add_host!
  options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'}
  assert_equal('http://www.basecamphq.com/foo/bar/33/', W.new.url_for(options) )
end

在您的情况下,最好的方法是使用 Rack 或您的 Web 服务器来执行重定向。在 Apache 中,您可以添加一个定义,例如

RewriteEngine on
RewriteRule ^(.+[^/])$ $1/  [R=301,L]

将不带斜杠的所有路由重定向到带有斜杠的相应路由。

或者,您可以使用rack-rewrite在您的 Rails 应用程序中的机架级别执行相同的任务。

于 2011-12-21T13:25:20.987 回答
1

防弹解决方案:

  before_action :force_trailing_slash

  ...

  private

  def force_trailing_slash
    return if trailing_slash?

    url = url_for \
      request.path_parameters
        .merge(request.query_parameters)
        .merge(trailing_slash: true)

    redirect_to url, status: :moved_permanently
  end

  def trailing_slash?
    URI(request.original_url).path.ends_with? '/'
  end
于 2021-02-25T16:34:44.840 回答
0

也许它适用于

match "/test$", :to => redirect("/test/")
于 2011-12-21T13:34:48.423 回答