不同浏览器请求头内容的编码、解码方式不同,只要后台按照浏览器的编码方式来编码对应的Content-Disposition内容,浏览器按照其对应的解码方式进行解码就不会出现中文文件名的乱码问题了。
首先,文件名作为参数保存Content-Disposition里也就是header头里,content-type指定的是响应文件在浏览器显示的编码,header头里的编码没法指定,浏览器不同,Content-Disposition值可以有以下几种编码格式 。
- 直接urlencode:
Content-Disposition: attachment;filename="struts2.0%E4%B8%AD%E6%96%87%E6%95%99%E7%A8%8B.chm"
- Base64编码:
Content-Disposition: attachment; filename="=?UTF8?B?c3RydXRzMi4w5Lit5paH5pWZ56iLLmNobQ==?="
- RFC2231规定的标准:
Content-Disposition: attachment; filename*=UTF-8''%E5%9B%9E%E6%89%A7.msg
- 直接ISO编码的文件名:
Content-Disposition: attachment;filename="测试.txt"
然后,各浏览器支持的对应编码格式为:
- IE浏览器,采用URLEncoder编码
- Opera浏览器,采用filename*方式
- Safari浏览器,采用ISO编码的中文输出
- Chrome浏览器,采用Base64编码或ISO编码的中文输出
- FireFox浏览器,采用Base64或filename*或ISO编码的中文输出
代码如下(亲测有效,转载)
//设定文件名称
String filename = resultTitle.getOrgName() + "测试中文.doc";
//获取浏览器使用的编码
String agent = request.getHeader("USER-AGENT");
filename = URLEncoder.encode(filename, "UTF8");
// 如果没有UA,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的
String filenameConcat = "filename=\"" + filename + "\"";
if (agent != null) {
agent = agent.toLowerCase();
// IE浏览器,只能采用URLEncoder编码
if (agent.indexOf("msie") != -1) {
filenameConcat = "filename=\"" + filename + "\"";
}
// Opera浏览器只能采用filename*
else if (agent.indexOf("opera") != -1) {
filenameConcat = "filename*=UTF-8''" + filename;
}
// Safari浏览器,只能采用ISO编码的中文输出
else if (agent.indexOf("safari") != -1) {
filenameConcat = "filename=\"" + new String(filename.getBytes("UTF-8"), "ISO8859-1") + "\"";
}
// Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
else if (agent.indexOf("applewebkit") != -1) {
filename = MimeUtility.encodeText(filename, "UTF8", "B");
filenameConcat = "filename=\"" + filename + "\"";
}
// FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
else if (agent.indexOf("mozilla") != -1) {
filenameConcat = "filename*=UTF-8''" + filename;
}
}
response.setHeader("Content-Disposition", "attachment;" + filenameConcat);
目前,我测试的情况,在几个浏览器上都能正常输入中文文件名
但,也许浏览器不同版本,可能还会有乱码的情况…
转载自:不同浏览器下载文件 中文名字乱码解决
其他参考链接:
解决下载文件中文名称乱码(包括IE,edge,Firefox,chrome)(未亲测)