1.5 静态文件

2022-10-20 • 更新于 2022-10-28

开始

和之前一样,在开始前,先将基础的内容编写好。

在工作空间的 Cargo.toml 中,添加内容 "ch01/static-files"。然后创建 static-files 项目。将项目的 Cargo.toml 和 main.rs 里的内容编写好,准备工作就做好了。

准备静态文件

这里官方例子源码中有其自己的静态文件。当然我们也可以自己创建自己需要的静态文件。但是基本需要的不能够缺少。

创建 static 文件夹,和 src 同层级。然后在 static 下创建 index.html 文件,同时创建 images、js、css文件夹。再在 js 文件夹下创建 example.js,在 css 文件夹下创建 style.css。images 文件夹下放一张自己喜欢的图片就行(我的图片来自于 Pixiv)。

这里的静态文件部分的文件夹结构和官方例子不太一样,可以自己灵活处理。

这里给一下我的 index.html、style.css 和 exmaple.js 的内容。

(index.html)

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Actix Web Static Files</title>
    <link rel="stylesheet" href="css/style.css">
    <script src="js/exmaple.js"></script>
</head>
<body>
    <div class="navigate">
        <div class="nav-child">
            <div>Actix web 学习笔记</div>
        </div>
        <div class="nav-child">
            <div class="text-button">目录</div>
        </div>
        <div class="nav-child">
            <div class="text-button">关于</div>
        </div>
    </div>

    <div class="page-content">
        <div class="title">Actix web静态文件</div>
        <div class="page">
            <div class="section">现在正在学习 actix-web 静态文件的内容</div>
            <img src="image/75544465_竜少女p0.jpg" alt="">
        </div>
    </div>
</body>
</html>

(style.css)

body {
    margin: 0 0 0 0;
    padding: 0 0 0 0;
}

.navigate {
    width: 100%;
    height: 60px;
    background-image: linear-gradient(to bottom right,rgb(61,61,61), rgb(34,34,34));
    display: flex;
    position: fixed;
    justify-content: flex-start;
    align-items: center;
    top: 0px;
    box-shadow: 1px 4px 20px black;
    z-index: 1000;
    color: white;
}

.nav-child {
    margin-left: 20px;
    margin-right: 20px;
}

.text-button:hover {
    font-weight: bold;
    cursor: pointer;
}

.page-content {
    margin: 80px 10% 20px 10%;
}

.title {
    font-weight: bold;
}

(example.js)

console.log("Hello, actix-web");

index.html 中的导航栏部分的样式来自我其他的项目,其实也只是使用了 flex 布局,并且对其背景和阴影进行了处理。看起来会比较有质感。剩下的部分只是调整了下位置。

至于 js,官方例子代码中,是通过 jQuery 将 Html 中的 img 元素进行了旋转。个人感觉只需要体现到 actix-web 配置静态文件,并在访问时能够查看网页就行了。js 也是网页的一部分,能够执行就说明 actix-web 访问静态文件成功了,所以自己的 js 中只是简单的打印了一个字符串。

到这里,静态文件的准备工作就做完了。由于主要的部分不在编写静态文件上,目前不能在这上面花费太多时间。

显示网页

在 Cargo.toml 中,添加 actix-filesenv_loggerlog 的依赖。

[dependencies]
actix-web = "4.2.1"
actix-files = "0.6"
env_logger = "0.9"
log = "0.4"

回到 main.rs。首先配置下 Logger 中间件。

use actix_web::{HttpServer, App, middleware};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    HttpServer::new(|| {
        App::new()
            .wrap(middleware::Logger::default())
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

如果这时尝试运行,会发现打印的日志既有 actix_server 也有 actix_web

HttpServer::new() 之前再手动打印一条日志到控制台。这次使用了 log crate。

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    log::info!("starting HTTP server at http://localhost:8080");

    HttpServer::new(|| {...})
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

可以猜测 Logger 中间件也使用了 log crate或者类似的库。那么之前配置的 info 字段和这次 env_logger 过滤匹配的,都对应了 log 中的 info!()

日志中间件配置好了,现在开始配置静态文件。静态文件的配置使用到了 actix-files crate,通过 App::new().service() 配置。不过由于此处只配置了单个文件,所以相对没有那么复杂。

use actix_files::Files;
use actix_web::{HttpServer, App, middleware};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // log.....
    HttpServer::new(|| {
        App::new()
            //add here
            .service(Files::new("/", "./static/").index_file("index.html"))
            .wrap(middleware::Logger::default())
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

运行并访问网址,可以看到编写好的网页成功显示出来了。

回看官方代码注释。官方的静态文件结构如下:

static
├images
└root
 ├css
 ├js
 └index.html

注释的内容写道: > 为网站的根地址配置了一个静态文件树,同时指定了 index file(个人感觉可以称为默认文件或默认页面)。需要注意的是根路径应该作为最后一个项目来配置。路径按其定义顺序进行解析。如果把根路径的配置放在 /images 之前,那么将无法访问到静态图片。

那么之后我们来尝试验证一下这个注释。

验证注释

首先按照源码配置好静态图片。静态图片是直接显示了文件列表,配置的路径为 /images

use actix_files::Files;
use actix_web::{HttpServer, App, middleware};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    log::info!("starting HTTP server at http://localhost:8080");

    HttpServer::new(|| {
        App::new()
            // add here
            .service(Files::new("/images", "static/images").show_files_listing())
            .service(Files::new("/", "./static/").index_file("index.html"))
            .wrap(middleware::Logger::default())
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

首先尝试运行一下,看两个路径是否都能够访问。如果不能够访问,检查一下控制台的输出并解决。

那么现在能正常访问,如果把 /images 和根路径的配置顺序置换,会不会出现注释中说明的情况呢?马上进行尝试,将配置顺序置换,并再次运行。会发现根路径能够访问,但是在访问 /images 的时候返回了 404。

总结

  • App.service() 传入 actix_files::Files::new() 可配置静态文件。Files::new() 传入的两个参数,前者为挂载路径,即访问网站时的路径,后者为服务路径,即本地文件路径。本地文件路径的 .,或者说根目录为项目目录。
  • 在配置路径时,根路径要放在最后配置,不然会导致在根路径之后配置的路径无法访问。
actix-web学习笔记Rustactix-web学习笔记

学少何

不求上进的社畜……

1.6 综合篇

1.4 嵌套路由