在网站找了很多地方,都没找到详细的文件上传的代码。这里分享一下,yew框架如何进行文件上传,希望能够帮助到大家。
upload 方法
首页,我们写一个上传文件的方法
use gloo_net::http::{Method, Request};
use serde::de::DeserializeOwned;
use serde::Serialize;
use gloo_storage::{LocalStorage, Storage};
use std::format;
use web_sys::FormData;
pub async fn upload<'a, R>(url: &'a str, params: &FormData) -> Result<R, String>
where
R: Serialize + DeserializeOwned + Clone,
{
let res = Request::new(format!("{}{}", "http://localhost:3060", url).as_str())
// .header("Content-Type", "multipart/form-data") // 可能不需要这个content type
.body(params)
.method(Method::POST)
.send()
.await;
match res {
Ok(r) => match r.json::<R>().await {
Ok(r0) => Ok(r0),
Err(e) => Err(e.to_string()),
},
Err(e) => Err(e.to_string()),
}
}
我们web端上传文件,以FormData的格式上传,所以,params的类型为&FormData。然后,body()里面直接传入params参数就可以了。
上传组件
然后,我们写一个上传文件的组件:upload_file.rs。
use js_sys;
use serde_json;
use stylist::css;
use web_sys::{Event, FormData, HtmlInputElement};
use yew::prelude::*;
use crate::constants::upload; // 引入上面的upload方法,根据你的位置修改引入。
#[function_component]
pub fn UploadFile() -> Html {
let onchange = {
Callback::from(move |e: Event| {
let input: HtmlInputElement = e.target_unchecked_into();
let form_data = FormData::new().unwrap();
if let Some(files) = input.files() {
// 将选择的文件数据,转换成 web_sys 的 Blob 格式。
let files = js_sys::try_iter(&files)
.unwrap()
.unwrap()
.map(|v| web_sys::Blob::from(v.unwrap()));
// 因只上传单个文件,files的长度为1
for file in files {
form_data.append_with_blob("file", &file).unwrap();
}
}
wasm_bindgen_futures::spawn_local(async move {
// 调用上面的 upload 方法,进行文件上传。
let res: Result<serde_json::Value, String> =
upload("/upload/image", &form_data).await;
log::info!("上传成功 {:?}", res);
})
})
};
html! {
<input type="file" {onchange} />
}
}
组件如下图,当我们点击选择文件的时候,它就上传成功了