【发布时间】:2022-08-18 00:59:15
【问题描述】:
我有一个充当代理的 Rust 控制台应用程序。从用户的角度来看,有一个 Web UI 前端。这包含一个按钮,当被调用时将触发对 rust 服务的 GET 请求。这又会调用一个返回 CSV 文件的外部端点。
我想要做的是当用户单击按钮时将文件下载到浏览器。现在我将 CSV 文件的内容返回到浏览器而不是文件本身。
当用户单击按钮时,它将请求路由到下载文件防锈功能...
pub async fn serve(listen_addr: SocketAddr) {
tokio::spawn(license::load());
let detectservices = Router::new()
.route(\"/downloadfile\", get(detectservices::downloadfile));
serve_message_apis().await;
info!(\"API server listening on {listen_addr}\");
Server::bind(&listen_addr)
.serve(app.into_make_service())
.await
.unwrap();
}
将调用外部端点(本例中为 docker 容器)并返回文件的 downloadfile 函数
pub async fn downloadfile() -> Result<Json<String>, ApiError> {
println!(\"downloadfile\");
let endpoint = \"http://127.0.0.1:7453/api/CSV/DownloadFile\";
let filename = \"local_jg_1-doc_637958283544997211.csv\".to_owned();
let mut path = String::new();
path += &endpoint;
path += \"?filename=\";
path += &filename;
println!(\"endpoint = {} filename = {}\", endpoint, filename);
println!(\"path = {}\", path);
let response = reqwest::get(path).await?;
let tmp_dir = Builder::new().prefix(\"example\").tempdir()?;
let mut dest = {
let fname = response
.url()
.path_segments()
.and_then(|segments| segments.last())
.and_then(|name| if name.is_empty() { None } else { Some(name) })
.unwrap_or(\"tmp.csv\");
println!(\"file to download: \'{}\'\", fname);
let fname = tmp_dir.path().join(fname);
println!(\"will be located under: \'{:?}\'\", fname);
File::create(fname)?
};
println!(\"dest {:?}\", dest);
let content = response.text().await?;
println!(\"content {:?}\", content);
copy(&mut content.as_bytes(), &mut dest)?;
Ok(Json(content))
}
我理解我获取内容的原因是因为我将内容字符串作为 JSON 返回 - 这是有道理的 - 但是我需要更改什么来返回文件本身以便浏览器直接为用户下载它?
-
要告诉浏览器下载文件而不是将其作为文本加载到浏览器中,您需要设置
Content-Disposition: attachment; filename=\"MyFileName.csv\"标头。你可能想设置Content-Type: text/csv。 stackoverflow.com/questions/393647/response-content-type-as-csv
标签: rust