开始
和之前一样,在开始前,先将基础的内容编写好。
在工作空间的 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-files
、env_logger
和 log
的依赖。
[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()
传入的两个参数,前者为挂载路径,即访问网站时的路径,后者为服务路径,即本地文件路径。本地文件路径的.
,或者说根目录为项目目录。 - 在配置路径时,根路径要放在最后配置,不然会导致在根路径之后配置的路径无法访问。