问题描述
在 NodeJS 中,可以像这样定义路由:
app.get('/:x',(req,res) => {
console.log(req.params.x)
res.sendStatus(200)
});
我想上传一个带有 id
标识符的文件,这样可以写入类似 img.save(format!("{}.png",id));
的内容。
我目前的代码:
use actix_multipart::Multipart;
use actix_web::{web,App,HttpServer,Responder};
use futures_util::{StreamExt,TryStreamExt};
use serde::Deserialize;
use image::ImageFormat;
async fn get() -> impl Responder {
web::HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(include_str!("../page.html"))
}
async fn post(mut payload: Multipart) -> impl Responder {
if let Ok(Some(mut field)) = payload.try_next().await {
println!("field: {:.?}",field);
let content_type = field.content_disposition();
println!("content_type: {:.?}",content_type);
if let Some(filename) = content_type.unwrap().get_filename() {
println!("filename: {:.?}",filename);
}
let mut full_vec: Vec<u8> = Vec::new();
while let Some(Ok(chunk)) = field.next().await {
full_vec.append(&mut chunk.to_vec());
}
println!("full_vec: {}",full_vec.len());
let img = image::load_from_memory_with_format(&full_vec,ImageFormat::Png)
.expect("Image load error");
img.save("img.png");
}
web::HttpResponse::Ok().finish()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Started.");
// Starts server
HttpServer::new(move || {
App::new()
// Routes
.route("/",web::get().to(get))
.route("/",web::post().to(post))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
HTML 将被模板化以在表单操作中包含 ID(在更一般的用例中,它们可能是多个具有不同 ID 的表单)。
<!DOCTYPE html>
<html>
<body>
<!-- <form id="form" action="/<% id %>" method="post"> -->
<form id="form" action="/" method="post">
<input type="file" name="file" required><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
解决方法
使用 https://actix.rs/docs/extractors/。
变化:
-
async fn post(mut payload: Multipart)
→async fn post(path: web::Path<String>,mut payload: Multipart)
-
.route("/",web::post().to(post))
→.route("/{id}",web::post().to(post))
-
<form id="form" action="/" method="post">
→<form id="form" action="/someTestId" method="post">