本指南假定您瞭解 Rack 協議和 Rack 概念,例如中介軟體、URL 對映和 Rack::Builder
。
1 Rack簡介
Rack 為在 Ruby 中開發 Web 應用程式提供了一個最小的、模組化的和適應性強的介面。通過以儘可能簡單的方式包裝 HTTP 請求和回應,它將用於 Web 伺服器、Web 框架和軟體(所謂的中介軟體)的 API 統一併提煉為單個方法呼叫。
解釋 Rack 的工作原理不在本指南的範圍內。如果你 不熟悉Rack的基礎知識,你應該檢視資源 以下部分。
2 Rails 上 Rack
2.1 Rails 應用程式的 Rack 物件
Rails.application
是 Rails 的主要 Rack 應用程式物件
應用。任何 Rack 相容的網路伺服器都應該使用
Rails.application
物件為 Rails 應用程式提供服務。
2.2 bin/rails server
bin/rails server
完成建立 Rack::Server
物件和啟動 Web 伺服器的基本工作。
以下是 bin/rails server
如何建立 Rack::Server
的實例
Rails::Server.new.tap do |server|
require APP_PATH
Dir.chdir(Rails.application.root)
server.start
end
Rails::Server
繼承自 Rack::Server
並以這種方式呼叫 Rack::Server#start
方法:
class Server < ::Rack::Server
def start
# ...
super
end
end
2.3 rackup
要使用 rackup
而不是 Rails' bin/rails server
,您可以將以下內容放入 Rails 應用程式根目錄的 config.ru
中:
# Rails.root/config.ru
require_relative "config/environment"
run Rails.application
並啟動伺服器:
$ rackup config.ru
要了解有關不同 rackup
選項的更多資訊,您可以執行:
$ rackup --help
2.4 開發和自動重灌
中介軟體載入一次,不會被監控更改。您必須重新啟動伺服器才能在正在執行的應用程式中反映更改。
3 Action Dispatcher Middleware Stack
許多 Action Dispatcher 的內部元件是作為 Rack 中介軟體實現的。 Rails::Application
使用 ActionDispatch::MiddlewareStack
結合各種內外中介軟體,形成一個完整的 Rails Rack 應用。
ActionDispatch::MiddlewareStack
是 Rails'相當於 Rack::Builder
,
但的目標在於提供更好的靈活性和更多功能,以滿足 Rails 的要求。
3.1 檢查中介軟體堆疊
Rails 有一個方便的命令來檢查正在使用的中介軟體堆疊:
$ bin/rails middleware
對於新產生的 Rails 應用程式,這可能會產生如下結果:
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::MethodOverride
use ActionDispatch::RequestId
use ActionDispatch::RemoteIp
use Sprockets::Rails::QuietAssets
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::ActionableExceptions
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ContentSecurityPolicy::Middleware
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use Rack::TempfileReaper
run MyApp::Application.routes
此處顯示的預設中介軟體(以及其他一些中介軟體)均在下面的 內部中介軟體 部分中進行了總結。
3.2 設定中介軟體棧
Rails 提供了一個簡單的設定介面 config.middleware
,用於通過 application.rb
或環境特定的設定檔案 environments/<environment>.rb
新增、刪除和修改中介軟體堆疊中的中介軟體。
3.2.1 新增中介軟體
您可以使用以下任一方法向中介軟體堆疊新增新的中介軟體:
config.middleware.use(new_middleware, args)
- 在中介軟體堆疊的底部新增新的中介軟體。config.middleware.insert_before(existing_middleware, new_middleware, args)
- 在中介軟體堆疊中指定的現有中介軟體之前新增新中介軟體。config.middleware.insert_after(existing_middleware, new_middleware, args)
- 在中介軟體堆疊中指定的現有中介軟體之後新增新的中介軟體。
# 設定/應用程式.rb
# 將 Rack::BounceFavicon 推到底部
config.middleware.use Rack::BounceFavicon
# 在 ActionDispatch::Executor 後新增 Lifo::Cache。
# 將 { page_cache: false } 引數傳遞給 Lifo::Cache。
config.middleware.insert_after ActionDispatch::Executor, Lifo::Cache, page_cache: false
3.2.2 交換中介軟體
您可以使用 config.middleware.swap
交換中介軟體堆疊中的現有中介軟體。
# 設定/應用程式.rb
# 用 Lifo::ShowExceptions 替換 ActionDispatch::ShowExceptions
config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions
3.2.3 刪除中介軟體
將以下行新增到您的應用程式設定中:
# 設定/應用程式.rb
config.middleware.delete ActionDispatch::Executor
現在,如果您檢查中介軟體堆疊,您會發現 ActionDispatch::Executor
是
不是它的一部分。
$ bin/rails middleware
(in /Users/lifo/Rails/blog)
use ActionDispatch::Static
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000001c304c8>
...
run Rails.application.routes
如果要刪除 session 相關的中介軟體,請執行以下操作:
# 設定/應用程式.rb
config.middleware.delete ActionDispatch::Cookies
config.middleware.delete ActionDispatch::Session::CookieStore
config.middleware.delete ActionDispatch::Flash
並刪除瀏覽器相關的中介軟體,
# 設定/應用程式.rb
config.middleware.delete Rack::MethodOverride
如果您希望在嘗試刪除不存在的專案時引發錯誤,請改用 delete!
。
# 設定/應用程式.rb
config.middleware.delete! ActionDispatch::Executor
3.3 內部中介軟體棧
Action Controller 的大部分功能都是作為中介軟體實現的。以下列表解釋了它們中的每一個的目的:
Rack::Sendfile
- 設定伺服器特定的 X-Sendfile 標頭。通過
config.action_dispatch.x_sendfile_header
選項設定它。
ActionDispatch::Static
- 用於從公共目錄提供靜態檔案。如果
config.public_file_server.enabled
是false
,則禁用。
Rack::Lock
- 將
env["rack.multithread"]
標誌設定為false
並將應用程式包裝在互斥鎖中。
ActionDispatch::Executor
- 用於開發過程中執行緒安全程式碼重新載入。
ActiveSupport::Cache::Strategy::LocalCache::Middleware
- 用於記憶體快取。此快取不是執行緒安全的。
Rack::MethodOverride
- 如果設定了
params[:_method]
,則允許覆蓋該方法。這是支援 PUT 和 DELETE HTTP 方法型別的中介軟體。
ActionDispatch::RequestId
- 為回應提供唯一的
X-Request-Id
標頭並啟用ActionDispatch::Request#request_id
方法。
ActionDispatch::RemoteIp
- 檢查 IP 欺騙攻擊。
Sprockets::Rails::QuietAssets
- 禁止資產請求的記錄器輸出。
Rails::Rack::Logger
- 通知日誌請求已經開始。請求完成後,重新整理所有日誌。
ActionDispatch::ShowExceptions
- 拯救應用程式返回的任何異常並呼叫一個異常應用程式,該應用程式將以終端使用者的格式包裝它。
ActionDispatch::DebugExceptions
- 負責記錄異常並在請求是本地的情況下顯示除錯頁面。
ActionDispatch::ActionableExceptions
- 提供了一種從 Rails 的錯誤頁面排程 actions 的方法。
ActionDispatch::Reloader
- 提供準備和清理callbacks,的目標在於幫助開發過程中重新載入程式碼。
ActionDispatch::Callbacks
- 提供 callbacks 在分派請求之前和之後執行。
ActiveRecord::Migration::CheckPending
- 檢查掛起的 migrations 並在任何 migrations 掛起時引發
ActiveRecord::PendingMigrationError
。
ActionDispatch::Cookies
- 為請求設定 cookies。
ActionDispatch::Session::CookieStore
- 負責將session儲存在cookies中。
ActionDispatch::Flash
- 設定快閃記憶體 keys。僅當
config.action_controller.session_store
設定為 value 時可用。
ActionDispatch::ContentSecurityPolicy::Middleware
- 提供 DSL 來設定 Content-Security-Policy 標頭。
Rack::Head
- 將 HEAD 請求轉換為
GET
請求併為它們提供服務。
Rack::ConditionalGet
- 新增對“Conditional
GET
”的支援,以便在頁面未更改時伺服器不回應任何內容。
Rack::ETag
- 在所有字串主體上新增 ETag 標頭。 ETag 用於驗證快取。
Rack::TempfileReaper
- 清理用於緩衝多部分請求的臨時檔案。
提示:可以在您的自定義 Rack 堆疊中使用上述任何中介軟體。
4 資源
4.1 學習Rack
4.2 理解中介軟體
回饋
我們鼓勵您幫助提高本指南的品質。
如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。
您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。
如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue。
關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區。