Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

响应与重定向

Responses and Redirects

提取器提供了一种在服务器函数内部访问请求数据的简便方法。Leptos 还提供了一种修改 HTTP 响应的方法,即使用 ResponseOptions 类型(参见 ActixAxum 类型的文档)和 redirect 辅助函数(参见 ActixAxum 的文档)。

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.