Content-Disposition值
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编码的中文输出
实现
/**
* 根据User-Agent 判断是什么浏览器 生成不同的header 防止下载文件 中文乱码
* @param request
* @param filename
* @return
* @throws UnsupportedEncodingException
* @see <a href="https://www.cnblogs.com/zhangzhen894095789/p/6479033.html">https://www.cnblogs.com/zhangzhen894095789/p/6479033.html</a>
*/
private String getFileName(HttpServletRequest request, String filename) throws UnsupportedEncodingException {
String userAgent = request.getHeader("User-Agent");
String new_filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.name());
// 如果没有UA,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的
String rtn = "filename=\"" + new_filename + "\"";
if (userAgent != null) {
userAgent = userAgent.toLowerCase();
// IE浏览器,只能采用URLEncoder编码
if (userAgent.contains("msie")) {
rtn = "filename=\"" + new_filename + "\"";
}
// Opera浏览器只能采用filename*
else if (userAgent.contains("opera")) {
rtn = "filename*=UTF-8''" + new_filename;
}
// Safari浏览器,只能采用ISO编码的中文输出
else if (userAgent.contains("safari")) {
rtn = "filename=\"" + new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"";
}
// Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
else if (userAgent.contains("applewebkit")) {
new_filename = MimeUtility.encodeText(filename, StandardCharsets.UTF_8.name(), "B");
rtn = "filename=\"" + new_filename + "\"";
}
// FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
else if (userAgent.contains("mozilla")) {
rtn = "filename*=UTF-8''" + new_filename;
}
}
return rtn;
}
使用:response.addHeader("Content-Disposition", "attachment;" + getFileName(request, exportFileName));