域名 AXUM.RS 将于 2025 年 10 月到期。我们无意再对其进行续费,如果你有意接续这个域名,请与我们取得联系。
  • AXUM.RS 现仅需人民币 3000 元(大写:叁仟元整。接受适度议价
  • 按照行业规则,AXUM.RS 到期后,大概率会进入长时间的赎回期,该期间内,如果你想拥有该域名,将要付出高额的费用
  • 我们已启用 AXUM.EU.ORG 域名,并将持续运营
  • 仅接受微信或支付宝交易
如果你对 AXUM.RS 有兴趣,请和我们进行联系:

axum 上传文件

启用 feature

要让 axum 支持文件上传,需要在 Cargo.toml 中显式的启用名为multipart的 feature:

axum =  {version = "0.3", features = ["multipart"] }

文件上传表单

首先,我们定义文件上传表单:

注意,要使用文件上传,必须将<form>enctype设置为multipart/form-data

注意,要使用文件上传,必须将<form>enctype设置为multipart/form-data

处理上传

/// 上传操作
async fn upload_file_action(
    ContentLengthLimit(mut multipart): ContentLengthLimit<Multipart, { MAX_UPLOAD_SIZE }>,
) -> Result<(HeaderMap, String), String> {
    if let Some(file) = multipart.next_field().await.unwrap() {
        let filename = file.file_name().unwrap().to_string(); // 上传的文件名
        let data = file.bytes().await.unwrap(); // 上传的文件的内容

        // 保存上传的文件
        //std::fs::write(&filename, &data).map_err(|err| err.to_string())?;
        tokio::fs::write(&filename, &data)
            .await
            .map_err(|err| err.to_string())?;

        return cn(format!(
            "【上传的文件】文件名:{:?}, 文件大小:{}",
            filename,
            data.len()
        ))
        .await;
    }
    cn(String::from("没有上传文件")).await
}
  • ContentLengthLimitMultipart 都是 axum 提供的extract。前者用于限制 HTTP 内容的长度,后者用于处理multipart/form-data

  • 获取到的变量是mut

ContentLengthLimitMultipart 都是 axum 提供的extract。前者用于限制 HTTP 内容的长度,后者用于处理multipart/form-data

首先,我们通过multipart.next_field()获取到提交过来的(下一个)type="file"的表单域。由它的方法名可知,它支持多文件上传。

  • file_name():获取上传的文件的文件名

  • bytes():获取上传的文件的内容

  • name():获取<input type="file" name="axum_rs_file">标签的name属于,此例中为axum_rs_file

file_name():获取上传的文件的文件名

bytes():获取上传的文件的内容

name():获取<input type="file" name="axum_rs_file">标签的name属于,此例中为axum_rs_file

最后,将上传的文件保存到服务器上:

tokio::fs::write(&filename, &data)
            .await
            .map_err(|err| err.to_string())?;

我们使用了tokio提供的异步 API,将上传的内容保存到服务器。

本章讨论了在 axum 实现文件上传功能,完整代码可以在我们的代码库中找到。

要查看完整内容,请先登录