You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Web框架中如何跨路由函数读取变量

Rust Web项目中跨路由传递变量的解决方案

因为POST和GET是两个独立的请求,内存里的局部变量无法直接共享,下面提供三种实用的实现方案:

方案1:通过URL查询参数传递(简单直接,适合临时传递)

直接在重定向时把参数拼到URL上,GET路由读取即可,无需额外依赖。

修改POST路由:

#[post("/select_date", data = "<time>")]
fn select_date(time: Form<SelectDate>) -> Result<Redirect, Error> {
    println!("{:#?}", time.date);
    // 对日期做URL编码,避免特殊字符破坏URL结构
    Ok(Redirect::to(&format!("/?f_time={}", urlencoding::encode(&time.date))))
}

需要在Cargo.toml添加URL编码依赖:

urlencoding = "2.1"

修改GET路由接收参数:

use actix_web::web::Query;
use std::collections::HashMap;

#[get("/")]
async fn index(user: Option<User>, query: Option<Query<HashMap<String, String>>>) -> Template {
    // 从查询参数中提取f_time,无值时用空字符串
    let f_time = query
        .and_then(|q| q.get("f_time").cloned())
        .unwrap_or_default();
    Template::render("index", json!({ "user": user, "f_time": f_time }))
}

方案2:使用Session存储(适合用户关联的临时数据)

如果不想把参数暴露在URL里,或者需要和用户绑定,可以用Session存储。以Actix-web为例:

  1. 添加依赖到Cargo.toml:
actix-session = "0.7"
serde = { version = "1.0", features = ["derive"] }
  1. 在应用初始化时配置Session中间件:
use actix_session::{Session, CookieSessionStore, SessionMiddleware};
use rand::Rng;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // 生产环境请将密钥存在配置文件,不要硬编码
    let secret_key = rand::thread_rng().gen::<[u8; 32]>();

    HttpServer::new(move || {
        App::new()
            .wrap(SessionMiddleware::new(
                CookieSessionStore::default(),
                &secret_key,
            ))
            .service(select_date)
            .service(index)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
  1. 修改POST路由存入Session:
use actix_session::Session;

#[post("/select_date", data = "<time>")]
fn select_date(time: Form<SelectDate>, session: Session) -> Result<Redirect, Error> {
    println!("{:#?}", time.date);
    // 将日期存入Session
    session.insert("f_time", &time.date)?;
    Ok(Redirect::to("/"))
}
  1. 修改GET路由从Session读取:
#[get("/")]
async fn index(user: Option<User>, session: Session) -> Template {
    // 从Session读取值,无值时用空字符串
    let f_time = session.get::<String>("f_time").unwrap_or_default();
    // 若无需保留数据,可读取后删除:session.remove("f_time");
    Template::render("index", json!({ "user": user, "f_time": f_time }))
}

方案3:使用数据库/缓存(适合长期或全局共享数据)

如果需要长期存储数据,或者让多个请求/用户共享,可以用数据库或缓存。以SQLite为例:

  1. 添加依赖:
sqlx = { version = "0.7", features = ["sqlite", "runtime-actix-native-tls"] }
  1. 初始化数据库连接:
use sqlx::SqlitePool;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let pool = SqlitePool::connect("sqlite:data.db").await.unwrap();
    // 初始化数据表(首次运行时执行)
    sqlx::query("CREATE TABLE IF NOT EXISTS user_data (user_id INTEGER, f_time TEXT)")
        .execute(&pool)
        .await
        .unwrap();

    HttpServer::new(move || {
        App::new()
            .data(pool.clone())
            .service(select_date)
            .service(index)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
  1. 修改POST路由存入数据库(假设用户有唯一ID):
#[post("/select_date", data = "<time>")]
async fn select_date(
    time: Form<SelectDate>,
    user: Option<User>,
    pool: web::Data<SqlitePool>,
) -> Result<Redirect, Error> {
    if let Some(user) = user {
        // 插入或更新用户的日期数据
        sqlx::query("INSERT OR REPLACE INTO user_data (user_id, f_time) VALUES (?, ?)")
            .bind(user.id)
            .bind(&time.date)
            .execute(pool.get_ref())
            .await?;
    }
    Ok(Redirect::to("/"))
}
  1. 修改GET路由从数据库读取:
#[get("/")]
async fn index(
    user: Option<User>,
    pool: web::Data<SqlitePool>,
) -> Template {
    let f_time = if let Some(user) = user {
        sqlx::query_scalar("SELECT f_time FROM user_data WHERE user_id = ?")
            .bind(user.id)
            .fetch_optional(pool.get_ref())
            .await
            .unwrap_or_default()
            .unwrap_or_default()
    } else {
        String::new()
    };
    Template::render("index", json!({ "user": user, "f_time": f_time }))
}

内容的提问来源于stack exchange,提问作者GranBoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:15:33