如何让Rust Actix-web返回可在浏览器直接预览的静态PDF文件
如何在Actix-web中实现Chrome浏览器内直接预览PDF而非触发下载?
我使用Actix-web提供静态PDF文件预览功能,当前代码如下,但通过http://localhost:8080/namefile访问时,Chrome浏览器会弹出下载窗口,希望实现浏览器内直接预览PDF。
现有Rust代码
use actix_web::{error::ErrorBadRequest, web, App, HttpRequest, HttpServer, Responder}; use actix_files::{Files, NamedFile}; use mime::Mime; async fn namefile(req: HttpRequest) -> impl Responder { let pdf_file_path = "/Users/xiaoqiangjiang/source/reddwarf/backend/rust-learn/doc/sample.pdf"; match NamedFile::open(&pdf_file_path) { Ok(file) => { let content_type: Mime = "application/pdf".parse().unwrap(); return NamedFile::set_content_type(file, content_type).into_response(&req); } Err(e) => { return ErrorBadRequest("File not Found").into(); } } } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .route("/namefile", web::get().to(namefile)) .service(Files::new("/static", "./static").show_files_listing()) }) .bind("127.0.0.1:8080")? .run() .await }
对应的Cargo.toml配置
[package] name = "rust-learn" version = "0.1.0" edition = "2018" [dependencies] actix-web = "4" actix-files = "0.6.2" mime = "0.3.17" [profile.release] debug = true
解决方案
问题核心在于响应的Content-Disposition头部:默认情况下NamedFile会添加attachment值,强制浏览器触发下载。要实现内嵌预览,需将该头部设置为inline,同时确保Content-Type保持application/pdf。
修改后的namefile函数如下:
async fn namefile(req: HttpRequest) -> impl Responder { let pdf_file_path = "/Users/xiaoqiangjiang/source/reddwarf/backend/rust-learn/doc/sample.pdf"; match NamedFile::open(&pdf_file_path) { Ok(mut file) => { let content_type: Mime = "application/pdf".parse().unwrap(); // 设置Content-Disposition为inline,告知浏览器内嵌预览 file = file.set_content_type(content_type) .set_header(actix_web::http::header::CONTENT_DISPOSITION, "inline"); file.into_response(&req) } Err(_) => ErrorBadRequest("File not Found").into(), } }
说明
set_header方法添加Content-Disposition: inline头部,明确告诉浏览器直接在页面内渲染文件内容。- Chrome原生支持PDF预览,只要
Content-Type和Content-Disposition两个头部设置正确,就能自动在浏览器内打开PDF,无需触发下载。
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

