常量
ILLEGAL_HEADER_VALUE_REGEX | = | /[\x00-\x08\x0A-\x1F]/ |
实例公共方法
redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args) 链接
对于 redirect_back_or_to
的软弃用别名,其中 fallback_location
位置作为关键字参数提供,而不是第一个位置参数。
来源:显示 | 在 GitHub 上
# File actionpack/lib/action_controller/metal/redirecting.rb, line 122 def redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args) redirect_back_or_to fallback_location, allow_other_host: allow_other_host, **args end
redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options) 链接
如果可能,将浏览器重定向到发出请求的页面(引用方),否则重定向到提供的默认回退位置。
引用方信息是从请求的 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
选项
-
:allow_other_host
- 允许或禁止重定向到与当前主机不同的主机,默认为 true。
可以传递给 redirect_to
的所有其他选项都作为选项被接受,并且行为相同。
来源:显示 | 在 GitHub 上
# File actionpack/lib/action_controller/metal/redirecting.rb, line 149 def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options) if request.referer && (allow_other_host || _url_host_allowed?(request.referer)) redirect_to request.referer, allow_other_host: allow_other_host, **options else # The method level `allow_other_host` doesn't apply in the fallback case, omit # and let the `redirect_to` handling take over. redirect_to fallback_location, **options end end
redirect_to(options = {}, response_options = {}) 链接
将浏览器重定向到 options
中指定的目标。此参数可以是以下任何一个
-
Hash
- URL 将通过调用 url_for 并传入options
来生成。 -
Record
- URL 将通过调用 url_for 并传入options
来生成,这将引用该记录的命名 URL。 -
以
protocol://
(如http://
)或协议相对引用(如//
)开头的String
- 直接作为重定向目标传递。 -
不包含协议的
String
- 当前协议和主机将被附加到字符串的前面。 -
Proc
- 一个将在控制器上下文中执行的代码块。应该返回redirect_to
接受的任何选项。
示例
redirect_to action: "show", id: 5
redirect_to @post
redirect_to "http://www.rubyonrails.org"
redirect_to "/images/screenshot.jpg"
redirect_to posts_url
redirect_to proc { edit_post_url(@post) }
重定向将作为 302 Found
标头发生,除非使用 :status
选项另行指定。
redirect_to post_url(@post), status: :found
redirect_to action: 'atom', status: :moved_permanently
redirect_to post_url(@post), status: 301
redirect_to action: 'atom', status: 302
状态代码可以是标准的 HTTP 状态代码 作为整数,或者是一个表示小写、下划线和符号化的描述的符号。请注意,状态代码必须是 3xx HTTP 代码,否则不会发生重定向。
如果您正在使用除 GET 或 POST 之外的 XHR 请求,并在请求后重定向,那么一些浏览器将使用原始请求方法来遵循重定向。这可能会导致不希望有的行为,例如双重 DELETE。要解决此问题,您可以返回 303 See Other
状态代码,它将使用 GET 请求进行跟踪。
redirect_to posts_url, status: :see_other
redirect_to action: 'index', status: 303
还可以将闪存消息作为重定向的一部分进行分配。有两个用于常用闪存名称 alert
和 notice
的特殊访问器,以及一个通用的 flash
存储桶。
redirect_to post_url(@post), alert: "Watch it, mister!"
redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
redirect_to({ action: 'atom' }, alert: "Something serious happened")
redirect_to
后面的控制器中的语句将被执行,因此 redirect_to
不会停止函数的执行。要立即在 redirect_to
之后终止函数的执行,请使用 return。
redirect_to post_url(@post) and return
开放式重定向保护
默认情况下,Rails
会保护您的应用免受重定向到外部主机的攻击,以确保您的应用安全,这种攻击被称为开放式重定向。注意:这是 Rails
7.0 中的新默认值,升级后通过取消 config/initializers/new_framework_defaults_7_0.rb
中 raise_on_open_redirects
的注释来启用它。
这里 redirect_to
会自动验证可能不安全的 URL。
redirect_to params[:redirect_url]
在发生不安全重定向的情况下,会引发 UnsafeRedirectError
。
要允许任何外部重定向,请传递 allow_other_host: true
,尽管在这种情况下使用用户提供的参数是不安全的。
redirect_to "https://rubyonrails.net.cn", allow_other_host: true
有关内部和安全 URL 的更多信息,或如何在不安全的情况下回退到备用重定向 URL,请参阅 url_from
。
来源:显示 | 在 GitHub 上
# File actionpack/lib/action_controller/metal/redirecting.rb, line 103 def redirect_to(options = {}, response_options = {}) raise ActionControllerError.new("Cannot redirect to nil!") unless options raise AbstractController::DoubleRenderError if response_body allow_other_host = response_options.delete(:allow_other_host) { _allow_other_host } proposed_status = _extract_redirect_to_status(options, response_options) redirect_to_location = _compute_redirect_to_location(request, options) _ensure_url_is_http_header_safe(redirect_to_location) self.location = _enforce_open_redirect_protection(redirect_to_location, allow_other_host: allow_other_host) self.response_body = "" self.status = proposed_status end
url_from(location) 链接
验证传入的 location
是否是安全的内部 URL,并返回它,如果不是则返回 nil。用于包装 params 提供的重定向 URL 并在不安全的情况下回退到备用 URL 以进行重定向。
redirect_to url_from(params[:redirect_url]) || root_url
如果 location
与 request.host
在同一主机上,则它被认为是内部的,并且是安全的。
# If request.host is example.com:
url_from("https://example.com/profile") # => "https://example.com/profile"
url_from("http://example.com/profile") # => "http://example.com/profile"
url_from("http://evil.com/profile") # => nil
子域名被认为是主机的一部分。
# If request.host is on https://example.com or https://app.example.com, you'd get:
url_from("https://dev.example.com/profile") # => nil
注意:与 url_for 类似,后者从应用内部的不同选项生成内部 URL,例如 url_for(@post)
。但是,url_from
旨在接收外部参数以验证,例如 url_from(params[:redirect_url])
。
来源:显示 | 在 GitHub 上
# File actionpack/lib/action_controller/metal/redirecting.rb, line 203 def url_from(location) location = location.presence location if location && _url_host_allowed?(location) end