Rust开发案例库-静态服务器

为了学习Rust, 我启动了一个叫rust-learning-example项目,主要是分享一些学习Rust开发的案例库,根据一些小案例由浅入深进行Rust开发学习。

Github地址:

https://github.com/zsf2025/rust-learning-example/tree/feat-axum

上一小节,我们学习了Axum「路由定义、请求解析、响应返回」基本用法(内容在feat-axum分支),今天我们就应用之前的基础搭建一个简单的静态文件服务器。(本章节代码在feat-axum_02)

📕静态文件服务器

目标 :学会用 Axum 提供静态资源(如 HTML、CSS、图片),熟悉 ServeDir 服务。

  • 核心功能:
    • 访问 GET / 返回 static/index.html(前端静态页面)
    • 访问 GET /assets/:file 读取 static/assets/ 下的文件(图片、CSS)
    • 404 页面:访问不存在的路由返回自定义 404 HTML
  • 依赖:axum + tokio + tower-http(ServeDir)
  • 练习点:Router::nest 路由嵌套、ServeDir 静态资源服务、自定义错误响应。
一、访问 GET / 返回 static/index.html(前端静态页面)
  1. 在根目录下创建static目录,在static目录下创建index.html文件,内容如下:
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>默认加载</title>
</head>
<body>
    <h1>你好~</h1>
    <p>访问没有的路径都会到这里~~~</p>
</body>
</html>
  1. Axum在0.8版本后移除了内置的serve-dir,推荐使用tower-httpfs特性实现静态文件服务。我们可以按需启用tower-http的一些常用特性:
功能 所需特性
静态文件服务 fs
跨域(CORS) cors
压缩 compression
日志 logging
限流 rate-limit
设置响应头 set-header
API Key认证 auht
健康检查 health-check
反向代理 proxy

这里我主要用到fs,在终端输入以下命令加载依赖:

复制代码
cargo add tower-http --features fs
  1. 修改我们上一章节的main.rs,实现GET / 返回步骤一创建的index.html文件
rust 复制代码
// 引入tower_http的fs特性下静态文件服务
use tower_http::services::ServeDir;
// Rust操作文件路径的工具类
use std::path::PathBuf;

...
  // 注意掉,这行代码,在这个后面添加我们的静态服务,注释掉主要是为了GET / 能访问到index.html
  // .route("/", get(hello_world));

  // fallback_service 是一个兜底服务,当所有路由都匹配失败时,会调用这个服务.
  // GET / 如果没有路由会找static/index.html, GET /test 没有路径,会找static/test.html,找不到再找static/test/index.html
  .fallback_service(ServeDir::new(PathBuf::from("static")));
...

👏运行cargo run, 浏览器访问http://127.0.0.1:3000, 可以看到成功加载了static/index.html页面。

二、访问 GET /assets/:file 读取 static/assets/ 下的文件(图片、CSS)

其实在上一步已经有一个静态服务器,但我需要使用nest_serviceServeDir服务嵌套到/assets路径下,实现GET /assets/:file 读取 static/assets/ 下的文件。

rust 复制代码
...
  // 嵌套静态文件服务到 /assets 路径下
  .nest_service("/assets", ServeDir::new(PathBuf::from("static/assets")))
  .fallback_service(ServeDir::new(PathBuf::from("static")));
...

启动项目,浏览器访问http://127.0.0.1:3000/assets/style.css, 可以看到成功加载了static/assets/style.css`文件。

404 页面:访问不存在的路由返回自定义 404 HTML

这里我们只要用fallback替换fallback_service即可。fallback是接收一个兜底的函数,当所有路由都匹配失败时,会调用这个函数。

rust 复制代码
// 定义我们fallback函数
async fn fallback() -> impl IntoResponse {
     println!("没有匹配到路由");
    // 自定义404页面
    (StatusCode::NOT_FOUND, "页面未找到")
}
...
  // 自定义 fallback 处理函数
  .fallback(fallback);
...

到这里我们会发现GET /无法访问index.html文件了,因为fallback覆盖了fallback_service注册器。这里涉及到一个Axum的路由匹配优先级问题。

  • 精确匹配的路由 ( .route() 、 .nest() 等)具有最高优先级
  • 服务路由 ( .nest_service() )次之
  • fallback 处理器 ( .fallback_service() 、 .fallback() )优先级最低

所有这里我们需要修改一下, 把fallback放在fallback_service里面进行兜底

rust 复制代码
...
  // 自定义 fallback 处理函数
   .fallback_service(
        ServeDir::new("static")
            .fallback(fallback.into_service())
    );
...

OK, 现在我们可以访问http://127.0.0.1:3000,可以看到成功加载了static/index.html页面。访问不存在的路由会进行兜底,返回自定义的404页面。

👏总结:

  • 静态文件服务器的实现主要是利用了Axum的路由嵌套和tower-httpServeDir服务。
  • 我们可以通过nest_serviceServeDir服务嵌套到/assets路径下,实现GET /assets/:file 读取 static/assets/ 下的文件。
  • 当所有路由都匹配失败时,会调用fallback函数,返回自定义的404页面。

🤔课后作业

  • 处理static目录不存在场景
  • 实现一个简单的static下文件资源管理器,index.html返回的是static目录下的文件列表。是文件查看文件, 是目录可以继续查看目录下的文件。
相关推荐
起个名字费劲死了1 小时前
QT + Socket 客户端/服务端 公网通讯
服务器·c++·qt·socket
做萤石二次开发的哈哈1 小时前
萤石开放平台 萤石可编程设备 | 设备 Python SDK 使用说明
开发语言·网络·python·php·萤石云·萤石
子有内涵1 小时前
【C++】红黑树实现
开发语言
降临-max1 小时前
JavaWeb企业级开发---Mybatis
java·开发语言·笔记·学习·mybatis
bing.shao1 小时前
golang 做AI任务链的优势和场景
开发语言·人工智能·golang
我是一只小青蛙8882 小时前
位图与布隆过滤器:高效数据结构解析
开发语言·c++·算法
Object~2 小时前
4.const和iota
开发语言·前端·javascript
HarmonLTS2 小时前
Python Socket网络通信详解
服务器·python·网络安全
willingli2 小时前
c语言经典100题 61-70题
c语言·开发语言·算法