IE下载时中文文件名乱码解决

本文介绍了如何通过HTTP响应头Content-Disposition实现文件下载功能,并详细解释了不同浏览器对文件名编码的支持差异。此外,还提供了兼容新旧浏览器的编码实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载时会通过添加header

Content-Disposition: attachment;filename=xxx

来达到浏览器弹窗下载。


然后根据rfc2616,要求header使用iso-8859-1进行编码,于是遇到中文后一般会发生这种情况

String fname="中文";
String header=new String(fname.getBytes("UTF-8"),"ISO-8859-1");
response.addHeader("Content-Disposition: attachment;filename="+header);

因为rfc2616没有把Content-Disposition添加进标准中,所以各个浏览器对这个header的实现各不相同,
低版本IE:

request-->服务器编码文件名(一般UTF8)-->ISO-8859-1

response-->ISO-8859-1-->本机编码(中文系统就是GBK)

Chrome:

response-->ISO-8859-1-->UTF-8

这样的话Chrome就貌似正常了,但是如果服务器的编码是GBK,照样扑街。
对此,一般是在服务器编码header的时候根据UA分别编码。


后来RFC6266发布,将Content-Disposition添加到header标准,语法

content-disposition = "Content-Disposition" ":"
                            disposition-type *( ";" disposition-parm )

     disposition-type    = "inline" | "attachment" | disp-ext-type
                         ; case-insensitive
     disp-ext-type       = token

     disposition-parm    = filename-parm | disp-ext-parm

     filename-parm       = "filename" "=" value
                         | "filename*" "=" ext-value

     disp-ext-parm       = token "=" value
                         | ext-token "=" ext-value
     ext-token           = <the characters in token, followed by "*">

   Defined in [RFC2616]:

     token         = <token, defined in [RFC2616], Section 2.2>
     quoted-string = <quoted-string, defined in [RFC2616], Section 2.2>
     value         = <value, defined in [RFC2616], Section 3.6>
                   ; token | quoted-string

   Defined in [RFC5987]:

     ext-value   = <ext-value, defined in [RFC5987], Section 3.2>

同时给出一个兼容性方案

Content-Disposition:attachment;filename="8859-1编码的文件名";filename*=utf-8''UTF8编码的文件名


这是因为旧版本浏览器只识别

filename

 

而新版本浏览器会使用

filename*

忽略其他部分。

 

如此一来,不在需要根据UA,只需要直接同时提交2种编码文件名,新旧浏览器直接支持,同时也是符合http协议

        ByteArrayOutputStream boas = null;
        HttpHeaders header = new HttpHeaders();
        String filename = "明细清单.xls";
        String filename8859 = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        String filenameutf8 = null;
        try {
            filenameutf8 = URLEncoder.encode(filename, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        header.add("Content-Type", "application/vnd.ms-excel");
        header.add("Content-Disposition", "attachment;filename=" + filename8859 + ";filename*=utf-8''" + filenameutf8);
        return new ResponseEntity<>(boas.toByteArray(), header, HttpStatus.OK);

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值