HTTP協定提供了一些快取機制,最基本的就是Cache-Control。Cache-Control可以用來控制HTTP連線要如何被快取,例如最常見的用法就是透過max-age
參數來設定快取時間,搭配public
或是private
參數來控制快取的可見程度。不過Rocket框架本身並沒有對Cache-Control提供直接的支援,所以使用起來不是很方便。
Cache Response for Rocket Framework
「Cache Response for Rocket Framework」是筆者開發的套件,可以快速地替Rocket的HTTP回應加上Cache-Control機制。
Crates.io
Cargo.toml
rocket-cache-response = "*"
使用方法
rocket_cache_response
這個crate提供了CacheResponse
列舉,可以用來包裹任意的HTTP回應的型別,在HTTP回應中加上Cache-Control
欄位來進行快取的控制。CacheResponse
列舉提供的變體有以下幾種:
Public
:可以使所有(包括代理伺服器和CDN)的客戶端快取HTTP回應一段時間,在快取的有效時間中,客戶端不需要再向伺服器端重新發送HTTP請求。must_revalidate
參數可以用來控制過期的快取是否一定要再向伺服器端重新發送HTTP請求來驗證快取的有效性(驗證的方式可以是在HTTP標頭中夾帶其它的欄位資訊,讓伺服器可以去檢查),當伺服器回傳的HTTP狀態碼為304
(Not Modified),表示同意客戶端繼續使用快取,快取時間會重新計算。(一般的網頁瀏覽器不論有無must_revalidate
參數都會當作是有must_revalidate
參數來處理,但是代理伺服器和CDN就不一定了。)Private
:可以使最終客戶端(如網頁瀏覽器)快取HTTP回應一段時間,在快取的有效時間中,客戶端不需要再向伺服器端重新發送HTTP請求。NoCache
:允許所有客戶端快取HTTP回應,但每次使用快取時,客戶端都要向伺服器驗證快取的有效性,當伺服器回傳的HTTP狀態碼為304
(Not Modified),表示同意客戶端繼續使用快取。如果HTTP回應中沒有Cache-Control
欄位,通常就會被當作是NoCache
(no-cache
)。NoStore
:不允許所有客戶端快取HTTP回應。NoCacheControl
:不設定(改變)Cache-Control
欄位。
以下是一個使用範例:
#[macro_use]
extern crate rocket;
use rocket_cache_response::CacheResponse;
use chrono::prelude::*;
#[get("/")]
fn index() -> CacheResponse<String> {
CacheResponse::Public {
responder: format!("Current Time: {}\n\nTry to re-open this page repeatedly without pressing the refresh(F5) or forced-refresh(Ctrl+F5) buttons.", Utc::now().to_rfc3339()),
max_age: 10, // cached for seconds
must_revalidate: false,
}
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![index])
}
另外,CacheResponse
列舉還提供public_only_release
和private_only_release
這兩個關聯函數,可以用來設定只在使用release模式來編譯程式時才使用Public
或是Private
變體,否則就不設定Cache-Control
欄位(NoCacheControl
)。避免在程式開發階段,因為有用快取機制而導致一些麻煩的產生。