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;";			
	}
}

Q.E.D.


Think Big, Act Small