解决在谷歌浏览器下载时文件名包含逗号导致页面显示网页不可用问题

项目场景:

自己开发的文件服务项目在使用时测试反馈在下载文件时,文件名包含逗号时下载失败,无法跳转到下载链接页面。
项目使用springboot开发,文件的上传基于SpringMVC的表单文件上传。但是下载时由于需要下载原文件名,并且需要从数据库中查询到附件的中文名称再赋值给响应头,因此采用了流的方式返回文件。


问题描述

文件名如下,不得不吐槽真是清新脱俗而又不失温文尔雅的文件名(tmd)

 副本AAB,AIGJ,AIPG,BCAP,BESP,BHL,BKG,BOA,CPM--CPM.xlsx (21.08K) 

错误信息:

下载文件报错“:org.apache.catalina.connector.ClientAbortException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。

在跳转下载链接时页面响应如下
在这里插入图片描述


原因分析:

测试了一下中文逗号,可以正常下载。问题就很清晰了,附件下载时因文件名中含有英文逗号,被浏览器(本次使用chrome)中断,导致下载失败,页面显示网页不可用
在这里插入图片描述


解决方案:

设置响应头添加引号

查到是谷歌浏览器的一个bug,因此我们设置响应头时,对于filename加上引号处理
设置响应头Content-Disposition中实际效果如:content-disposition=attachment;fileName=“原文件名称”

 response.setHeader("Content-Disposition", "attachment;filename=\"" + FileUtil.encodeChineseDownloadFileName(request, realFileName) + "\"");

代码如下:
在这里插入图片描述

关于文件名下载乱码的解决方案

FileUtil.encodeChineseDownloadFileName(request, realFileName)

   /**
     * 浏览器下载时文件名乱码问题解决
     *
     * @param request
     * @param pFileName 文件名
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String encodeChineseDownloadFileName(HttpServletRequest request, String pFileName) throws UnsupportedEncodingException {
    
    
        String[] IE_BROWSER_SIGNALS = {
    
    "MSIE", "Trident", "Edge"};
        String FIREFOX = "Firefox";

        boolean isMSIE = false;
        String userAgent = request.getHeader("User-Agent");
        if (StringUtils.isBlank(userAgent)) {
    
    
            userAgent = request.getHeader("USER-AGENT");
        }
        for (String signal : IE_BROWSER_SIGNALS) {
    
    
            if (StringUtils.isNotBlank(userAgent) && userAgent.contains(signal)) {
    
    
                isMSIE = true;
            }
        }

        //返回的文件名
        String filename;
        if (isMSIE) {
    
    
            //IE浏览器的乱码问题解决
            filename = URLEncoder.encode(pFileName, "UTF-8");
            filename = StringUtils.replace(filename, "+", "%20");
        } else if (StringUtils.contains(userAgent, FIREFOX)) {
    
    
            filename = "=?UTF-8?B?" + (new String(org.apache.commons.codec.binary.Base64.encodeBase64(pFileName.getBytes("UTF-8")))) + "?=";
        } else {
    
    
            //万能乱码问题解决
            filename = new String(pFileName.getBytes("UTF-8"), "ISO-8859-1");
        }

        return filename;
    }

猜你喜欢

转载自blog.csdn.net/qq_29864051/article/details/131034538