使用Rust上传文件至Google Drive无法设置文件名,文件显示为Untitled
问题描述
向Google Drive上传文件时无法设置文件名,文件成功上传至Drive但显示为“Untitled”。
现有Rust代码
fn uploadFile(token: String, path: String, name: String, mimeType: String) { let mut headers = header::HeaderMap::new(); headers.insert("Authorization",format!("Bearer {token}").parse().unwrap()); headers.insert("Content-Type", format!("{mimeType}").parse().unwrap()); let form = multipart::Form::new() .text("name", name) .file("file", format!("{path}")).unwrap(); let client = reqwest::blocking::Client::new(); let res = client.post("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart") .headers(headers) .multipart(form) .send().unwrap() .text().unwrap(); println!("{}", res); }
上传后返回的JSON响应
{ "kind": "drive#file", "id": "1Zo5_lPcI7k02p4PQVI31aaroU1-mq4J_", "name": "Untitled", "mimeType": "application/pdf" }
可正常工作的curl命令
curl -X POST -L https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart \ -H "Authorization: Bearer " \ -F "metadata={name : ''};type=application/json;charset=UTF-8" \ -F "file=@;type="
问题原因
Google Drive的multipart上传要求将文件元数据(如文件名)放在单独的表单部分中,且该部分的Content-Type必须为application/json。当前Rust代码直接用.text("name", name)传递文件名,不符合API的参数格式要求,因此Drive忽略了该参数,默认使用“Untitled”作为文件名。
解决方案
修改代码,将元数据封装为JSON字符串,并作为指定类型的表单部分添加到multipart请求中,同时移除手动设置的Content-Type请求头(reqwest会自动处理multipart请求的Content-Type):
use serde_json::json; fn uploadFile(token: String, path: String, name: String, mimeType: String) { let mut headers = header::HeaderMap::new(); headers.insert("Authorization", format!("Bearer {token}").parse().unwrap()); // 构建包含文件名的元数据JSON let metadata = json!({ "name": name }).to_string(); let form = multipart::Form::new() // 添加元数据部分,指定Content-Type为application/json .part("metadata", multipart::Part::text(metadata) .mime_str("application/json") .unwrap()) .file("file", path) .unwrap(); let client = reqwest::blocking::Client::new(); let res = client.post("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart") .headers(headers) .multipart(form) .send() .unwrap() .text() .unwrap(); println!("{}", res); }
注意事项
- 需要在
Cargo.toml中添加对应依赖:
[dependencies] reqwest = { version = "0.11", features = ["blocking", "multipart"] } serde_json = "1.0" http = "0.2"
- 确保元数据部分的键为
metadata,且Content-Type设置正确,与curl命令的参数逻辑保持一致。
内容的提问来源于stack exchange,提问作者Jesus
相关产品推荐
相关产品推荐

