1.JAVA 服务端代码,下载前处理文件名
/**
* 中文编码转换, 典型的情况是下载中文名的文件时, 浏览器不能正确地显示汉字
*/
public static String convert(HttpServletRequest request, String fileName) {
if (fileName == null) {
throw new IllegalArgumentException("输入参数是null");
}
try{
String agent = request.getHeader("USER-AGENT");
if (null != agent && (-1 != agent.indexOf("MSIE") || -1 != agent.indexOf("Trident")||-1 != agent.indexOf("Edge"))) {
return URLEncoder.encode(fileName, "UTF8").replace("+", "%20");
}else if (null != agent && -1 != agent.indexOf("Safari")) {
return new String(fileName.getBytes("utf-8"), "ISO8859-1");
}else if (null != agent && -1 != agent.indexOf("Mozilla")) {
return "=?UTF-8?B?"+(new String(Base64.encodeBase64(fileName.getBytes("UTF-8"))))+"?=";
} else {
return fileName;
}
}catch(UnsupportedEncodingException ex){
return fileName;
}
}
2.Nginx 文件服务下载解决办法
http 下载文件时,中文文件名乱码的问题,一般在http header中是这样操作的:
"Content-Disposition","attachment;filename=文件名.xx;"
其实,按照 rfc231
, Content-Disposition
应该按照如下格式设置:
"Content-Disposition","attachment;filename*=utf-8'zh_cn'文件名.xx;"
只要严格按照标准设置以后,自然在各种浏览器下都会正常运行了。我们可以在nginx配置文件中做以上修改。
刚开始研究这个问题时,走了条弯路,以为只有火狐下才需要写成filename*=utf-8'zh_cn'文件名.xx
这样(实际是标准,各浏览器都支持)。不过也学到了Nginx下的条件逻辑运算写法,也记录一下:
Nginx 的配置中不支持 if 条件的逻辑与逻辑或运算 ,并且不支持 if 的嵌套语法,我们可以用变量的方式来实现:
具体方法为AND 就用变量叠加,OR就用0或1切换。
location / {
root /test/lestorage/resource;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
add_header 'Access-Control-Allow-Headers' 'Range';
## nginx中if不支持逻辑 || &&,不支持嵌套,变相实现
set $attach "0";
if ($arg_filename) {
set $attach "1";
}
set $firefox "0";
if ($http_user_agent ~* "Mozilla") {
set $firefox "1";
}
set $condition "${attach}${firefox}";
# 可以指定filename参数,允许浏览器强制下载文件
if ($condition = "10") {
add_header Content-Disposition "attachment; filename=$arg_filename;";
}
if ($condition = "11") {
## 解决火狐乱码
add_header Content-Disposition "attachment; filename*=utf-8'zh_cn'$arg_filename;";
}
}
评论区