§Session 和 Flash 範圍
§在 Play 中有何不同
如果您必須跨多個 HTTP 要求保留資料,您可以將它們儲存在 Session 或 Flash 範圍中。儲存在 Session 中的資料在整個使用者會話期間可用,而儲存在 Flash 範圍中的資料僅在下一個要求中可用。
§使用 Cookie
了解 Session 和 Flash 資料並非儲存在伺服器中,而是使用 HTTP Cookie 加入到每個後續 HTTP 要求中,這一點很重要。
由於 Session 和 Flash 是使用 Cookie 實作的,因此有一些重要的影響。
- 資料大小非常有限(最多 4 KB)。
- 您只能儲存字串值,儘管您可以將 JSON 序列化到 Cookie 中。
- Cookie 中的資訊對瀏覽器可見,因此可能會揭露敏感資料。
- Cookie 資訊對原始要求不可變,且僅對後續要求可用。
最後一點可能會造成混淆。當您修改 Cookie 時,您會提供資訊給回應,而 Play 必須再次解析它才能看到更新的值。如果您想要確保會話資訊是目前的,則您應該始終將會話修改與重新導向配對。
§會話組態
Cookie 的預設名稱為 PLAY_SESSION
。這可以透過在 application.conf 中組態金鑰 play.http.session.cookieName
來變更。
如果 Cookie 的名稱已變更,可以使用 設定和捨棄 Cookie 中所述的相同方法捨棄較早的 Cookie。
請參閱 組態會話 Cookie 以取得有關如何在 application.conf
中組態會話 Cookie 參數的更多資訊。
§Session Timeout / Expiration
預設情況下,Session 沒有技術超時。它會在使用者關閉網頁瀏覽器時過期。如果您需要特定應用程式的功能超時,您可以透過在 application.conf
中設定金鑰 play.http.session.maxAge
來設定 Session Cookie 的最長存留時間,這也會將 play.http.session.jwt.expiresAfter
設定為相同的值。maxAge
屬性會從瀏覽器中移除 Cookie,而 JWT exp
宣告會設定在 Cookie 中,並在給定的時間後使其失效。請參閱 設定 Session Cookie 以取得更多資訊。
§在 Session 中儲存資料
由於 Session 只是 Cookie,它也只是一個 HTTP 標頭。您可以像處理其他結果屬性一樣來處理 Session 資料
Redirect("/home").withSession("connected" -> "[email protected]")
請注意,這將取代整個 Session。如果您需要將元素新增到現有的 Session,只要將元素新增到輸入的 Session,並指定為新的 Session 即可
Redirect("/home").withSession(request.session + ("saidHello" -> "yes"))
您可以用相同的方式從輸入的 Session 中移除任何值
Redirect("/home").withSession(request.session - "theme")
§讀取 Session 值
您可以從 HTTP 要求中擷取輸入的 Session
def index: Action[AnyContent] = Action { request =>
request.session
.get("connected")
.map { user => Ok("Hello " + user) }
.getOrElse {
Unauthorized("Oops, you are not connected")
}
}
§捨棄整個 Session
有一個特殊操作可以捨棄整個 Session
Redirect("/home").withNewSession
§Flash 範圍
Flash 範圍的運作方式與 Session 完全相同,但有一個不同點
- 資料只會保留一個要求
重要:Flash 範圍僅應使用於在非 Ajax 簡單應用程式上傳送成功/錯誤訊息。由於資料僅保留至下一個要求,而且無法保證在複雜的 Web 應用程式中確保要求順序,因此 Flash 範圍會受到競爭條件影響。
以下是使用 Flash 範圍的幾個範例
def index: Action[AnyContent] = Action { implicit request =>
Ok {
request.flash.get("success").getOrElse("Welcome!")
}
}
def save: Action[AnyContent] = Action {
Redirect("/home").flashing("success" -> "The item has been created")
}
若要檢索檢視中的 Flash 範圍值,請新增一個隱含 Flash 參數
@()(implicit flash: Flash)
...
@flash.get("success").getOrElse("Welcome!")
...
在您的動作中,指定一個 implicit request =>
,如下所示
def index: Action[AnyContent] = Action { implicit request => Ok(views.html.index()) }
會根據隱含要求提供隱含 Flash 給檢視。
如果引發錯誤「找不到參數 flash 的隱含值:play.api.mvc.Flash」,則表示您的動作在範圍中沒有隱含要求。
下一步:主體剖析器
在此文件中發現錯誤?此頁面的原始程式碼可在 這裡 找到。在閱讀 文件準則 後,請隨時提交拉取要求。有問題或建議要分享?請前往 我們的社群論壇 與社群展開對話。