火狐文件下载乱码解决

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