略過內容 略過搜尋
命名空間
方法
R
U
包含模組

常數

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 位置提供為關鍵字參數,而不是第一個位置參數。

# 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(就是這樣)標頭中提取。這是選用標頭,出現在要求中的與瀏覽器安全性設定和使用者喜好有關。如果要求遺失此標頭,將會使用 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 的所有選項均接受作為選項,行為也相同。

# 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 中指定的目標。這個參數可以是下列任何一個

  • 雜湊 - 將透過呼叫具有 options 的 url_for 來產生網址。

  • 記錄 - 將透過呼叫具有 options 的 url_for 來產生網址,這將參考該記錄的名稱網址。

  • 字串,從 protocol:// 開始(例如 http://)或相對於協定的參考(例如 //) - 直接傳遞作為重新導向目標。

  • 字串,不包含協定 - 目前協定和主機會加置於字串之前。

  • 程序 - 將在控制器的內容中執行的區塊。應傳回 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 請求,並在請求後重新導向,則部分瀏覽器將使用原始請求方法來遵循重新導向。這可能會導致不希望的行為,例如雙重刪除。為了解決這個問題,你可以傳回一個 303 另尋他處 狀態碼,這將使用 GET 請求來遵循。

redirect_to posts_url, status: :see_other
redirect_to action: 'index', status: 303

也可以在重新導向中指定快閃訊息。針對一般使用的快閃名稱 alertnotice,以及一般用途的 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.rbraise_on_open_redirects 行的註解以選擇加入

在此,redirect_to 自動驗證潛在不安全的網址

redirect_to params[:redirect_url]

在不安全重新導向的情況下引發 UnsafeRedirectError

要允許任何外部重新導向,請傳遞 allow_other_host: true,不過在這種情況下,使用使用者提供的參數並不安全。

redirect_to "https://rubyonrails.org", allow_other_host: true

url_from,進一步了解什麼是內部和安全的網址,或如何在不安全的情況下備援至另一個重新導向網址。

# 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(位置)

驗證傳遞的位置是安全的內部網址,可以重新導向到該網址,如果不行,則傳回 nil。用於包裝由參數提供的重新導向網址並備援至其他重新導向網址

redirect_to url_from(params[:redirect_url]) || root_url

如果 位置 位於 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_for(@post)。不過,url_from 的目的是採用外部參數來驗證,例如在 url_from(params[:redirect_url]) 中。

# 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