Postman上传中文文件名乱码的根本原因是服务端解析Content-Disposition头时未正确处理filename扩展语法,HTTP规范要求UTF-8文件名必须用filename=utf-8''格式编码,而非直接使用filename字段;Postman v11+原生支持该标准,但若手动覆盖Content-Type或误设字段类型为text,则会破坏合规请求结构。

Postman 上传中文文件名时服务端收到乱码
根本原因不是 Postman 本身编码错误,而是服务端解析 Content-Disposition 头中 filename 字段时用了错误的字符集(比如 ISO-8859-1)。HTTP 规范里 filename 不支持 UTF-8 直接编码,必须用 filename* 扩展语法。
常见现象:前端传了 中文报告.xlsx,后端 request.getPart("file").getSubmittedFileName() 拿到的是 ???.xlsx 或 %E4%B8%AD%E6%96%87%E6%8A%A5%E5%91%8A.xlsx 但没解码。
- Spring Boot + Servlet 4.0+ 用户,确保用
part.getSubmittedFileName()—— 它内部已处理filename*,无需手动解码 - 老版本 Servlet(如 3.1)或自定义解析逻辑,必须检查是否调用了
URLDecoder.decode(filename, "UTF-8") - Tomcat 9 默认禁用
relaxedQueryChars,若 filename* 带单引号(utf-8''%E4%B8%AD...),需在conf/server.xml的 Connector 中加relaxedPathChars="|" rela xedQueryChars="|"
Postman 自身对中文文件名的支持边界
Postman 桌面版(v11+)对 form-data 中的中文文件名是原生支持的,它会自动按 RFC 6266 构造带 filename* 的请求头。但前提是:你没手动覆盖 Content-Type 或改写 Content-Disposition。
容易踩的坑:
- 在 Postman 的
Headers标签页里手动加了一行Content-Disposition: attachment; filename="中文.txt"—— 这会覆盖 Postman 自动生成的合规头,直接导致乱码 - 把
Body → form-data里的文件字段类型误设为text而非file,此时 Postman 当作文本发送,不走文件上传流程 - 使用 Postman 的 “Code” 功能生成 curl 命令后复制执行,curl 默认不处理中文 filename*,需加
--data-urlencode或改用-F参数
如何验证服务端返回的 Content-Disposition 是否合规
关键看响应头里有没有同时存在 filename 和 filename*,且后者值以 utf-8'' 开头并包含 URL 编码后的中文。
例如正确格式:
Postman 12.27.7 Windows x64 官方安装包,适用于 API 设计、调试、测试与协作。该系列包含 Enterprise 云端性能测试静态 IP 出口能力,以及接口规范标签管理改进,适合受限网络测试与规范资源组织场景。
Content-Disposition: attachment; filename="%E4%B8%AD%E6%96%87.txt"; filename*=utf-8''%E4%B8%AD%E6%96%87.txt
如果只看到 filename="?????.txt" 或 filename="%E4%B8%AD..." 但没有 filename*,说明服务端构造头的方式过时,需立即修复。
Java 示例(Servlet 4.0+):
response.setHeader("Content-Disposition",
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"; " +
"filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8"));Node.js(Express)示例:
res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(fileName)}`);Postman 里看不到中文文件名?先查这个设置
Postman v10.20+ 在下载响应时,若服务端返回的 Content-Disposition 合规,它会自动提取 filename* 并用于保存文件。但如果下载后文件名仍是 download.bin 或乱码,大概率是响应头缺失 filename*,而非 Postman 设置问题。
唯一需要手动干预的场景:你在 Postman 的 Tests 脚本里用 pm.response.headers.get("Content-Disposition") 解析文件名 —— 此时必须自己提取 filename* 部分,并用 decodeURIComponent() 解码,不能只截 filename= 后面的内容。
真正容易被忽略的点:很多 Java 开发者习惯用 URLEncoder.encode(fileName, "ISO-8859-1") 来“兼容旧浏览器”,这在 Postman 里反而必然失败 —— Postman 只认 filename* + UTF-8 编码,其他都是徒劳。

















