响应与重定向
Responses and Redirects
提取器提供了一种在服务器函数内部访问请求数据的简便方法。Leptos 还提供了一种修改 HTTP 响应的方法,即使用 ResponseOptions 类型(参见 Actix 或 Axum 类型的文档)和 redirect 辅助函数(参见 Actix 或 Axum 的文档)。
Extractors provide an easy way to access request data inside server functions. Leptos also provides a way to modify the HTTP response, using the ResponseOptions type (see docs for Actix or Axum types) and the redirect helper function (see docs for Actix or Axum).
ResponseOptions
在初始服务器渲染响应期间以及随后的任何服务器函数调用期间,ResponseOptions 通过上下文(context)提供。它允许你轻松设置 HTTP 响应的状态码,或向 HTTP 响应添加标头(headers),例如设置 cookie。
ResponseOptions is provided via context during the initial server rendering response and during any subsequent server function call. It allows you to easily set the status code for the HTTP response, or to add headers to the HTTP response, e.g., to set cookies.
#[server]
pub async fn tea_and_cookies() -> Result<(), ServerFnError> {
use actix_web::{
cookie::Cookie,
http::header::HeaderValue,
http::{header, StatusCode},
};
use leptos_actix::ResponseOptions;
// 从上下文中提取 ResponseOptions
// pull ResponseOptions from context
let response = expect_context::<ResponseOptions>();
// 设置 HTTP 状态码
// set the HTTP status code
response.set_status(StatusCode::IM_A_TEAPOT);
// 在 HTTP 响应中设置 cookie
// set a cookie in the HTTP response
let cookie = Cookie::build("biscuits", "yes").finish();
if let Ok(cookie) = HeaderValue::from_str(&cookie.to_string()) {
response.insert_header(header::SET_COOKIE, cookie);
}
Ok(())
}
redirect
对 HTTP 响应最常见的一种修改是重定向到另一个页面。Actix 和 Axum 的集成提供了一个 redirect 函数,使这一操作变得非常简单。
One common modification to an HTTP response is to redirect to another page. The Actix and Axum integrations provide a redirect function to make this easy to do.
#[server]
pub async fn login(
username: String,
password: String,
remember: Option<String>,
) -> Result<(), ServerFnError> {
const INVALID_CREDENTIALS: fn() -> ServerFnError = || -> ServerFnError {
ServerFnError::ServerError("Invalid credentials".into())
};
// 从上下文中获取 DB 连接池和身份验证提供者
// pull the DB pool and auth provider from context
let pool = pool()?;
let auth = auth()?;
// 检查用户是否存在
// check whether the user exists
let user: User = User::get_from_username(username, &pool)
.await
.ok_or_else(INVALID_CREDENTIALS)?;
// 检查用户提供的密码是否正确
// check whether the user has provided the correct password
match verify(password, &user.password)? {
// 如果密码正确...
// if the password is correct...
true => {
// 登录用户
// log the user in
auth.login_user(user.id);
auth.remember_user(remember.is_some());
// 并重定向到主页
// and redirect to the home page
leptos_axum::redirect("/");
Ok(())
}
// 如果密码错误,返回错误
// if not, return an error
false => Err(INVALID_CREDENTIALS()),
}
}
这个服务器函数随后可以在你的应用程序中使用。这个 redirect 与渐进增强的 <ActionForm/> 组件配合得很好:在没有 JS/WASM 的情况下,服务器响应将根据状态码和标头进行重定向。在有 JS/WASM 的情况下,<ActionForm/> 会检测服务器函数响应中的重定向,并使用客户端导航重定向到新页面。
This server function can then be used from your application. This redirect works well with the progressively-enhanced <ActionForm/> component: without JS/WASM, the server response will redirect because of the status code and header. With JS/WASM, the <ActionForm/> will detect the redirect in the server function response, and use client-side navigation to redirect to the new page.