`

HTTP协议header中Content-Disposition中文文件名乱码

阅读更多
在做文件下载时,当文件名为中文时,经常会出现乱码现象。
参考文章: http://blog.robotshell.org/2012/deal-with-http-header-encoding-for-file-download/

本文就详细给出案例来解决这一乱码问题,以及还一直未解决的一个疑问,欢迎大家一起来探讨。
大体的原因就是header中只支持ASCII,所以我们传输的文件名必须是ASCII,当文件名为中文时,必须要将该中文转换成ASCII。
转换方式有很多:
方式一:将中文文件名用ISO-8859-1进行重新编码,如headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("UTF-8"),"ISO-8859-1")+".txt");
方式二:可以对中文文件名使用url编码,如headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt");
疑问:中文文件名转换成ASCII后传给浏览器,浏览器遇到一堆ASCII,如何能正确的还原出来我们原来的中文文件名的呢?

实验案例:
乱码现象如下:

	@RequestMapping(value="/test/httpEntity1",method=RequestMethod.GET)
	public HttpEntity<String> testHttpEntity1() throws UnsupportedEncodingException{
		String body="abc";
		HttpHeaders headers=new HttpHeaders();
		headers.add("Content-disposition","attachment;filename=中国.txt");
		HttpEntity<String> ret=new HttpEntity<String>(body,headers);
		return ret;
	}

这里的filename直接使用中文文件,然后就造成了下面的乱码现象:


文件名后缀也完全变了。

原因就是header只支持ASCII,所以我们要把"中国"转换成ASCII。
解决方案一:将中文文件名用ISO-8859-1进行重新编码

@RequestMapping(value="/test/httpEntity",method=RequestMethod.GET)
	public HttpEntity<String> testHttpEntity() throws UnsupportedEncodingException{
		String body="abc";
		HttpHeaders headers=new HttpHeaders();
		headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("UTF-8"),"ISO-8859-1")+".txt");
		HttpEntity<String> ret=new HttpEntity<String>(body,headers);
		return ret;
	}

chrome为:

IE11为:



chrome解决了乱码现象,但IE没有。但是你是否想过,浏览器面对一堆Content-disposition:attachment;filename=中国.txt,它又是如何来正确显示的中文文件名"中国.txt"的呢,它肯定要对中国,重新进行UTF-8编码才能正确显示出"中国",即必须进行类似如下的操作:new String("中国".getBytes("ISO-8859-1"),"UTF-8"),才能正常显示出"中国.txt"。而IE11进行的类似操作为:new String("中国".getBytes("ISO-8859-1"),"GBK")。
同样的实验,只是把UTF-8改成GBK:

@RequestMapping(value="/test/httpEntity",method=RequestMethod.GET)
	public HttpEntity<String> testHttpEntity() throws UnsupportedEncodingException{
		String body="abc";
		HttpHeaders headers=new HttpHeaders();
		headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("GBK"),"ISO-8859-1")+".txt");
		HttpEntity<String> ret=new HttpEntity<String>(body,headers);
		return ret;
	}

chrome为:

IE11为:

IE11和chrmoe都能正确显示,面对Content-disposition:attachment;filename=Öйú.txt,浏览器也必须进行如下类似的操作才能正确还原出"中国",new String("Öйú".getBytes("ISO-8859-1"),"GBK")。
这里就可以提出我们的疑问了,浏览器面对中国、Öйú都能正确还原出"中国",选择UTF-8还是GBK,它到底是怎么做到的呢?依据又是什么呢?难道它是要计算出概率?这便是我的疑问,还请大家一起探讨和研究。

接下来说说其他的解决方案:
解决方案二:可以对中文文件名使用url编码

@RequestMapping(value="/test/httpEntity",method=RequestMethod.GET)
	public HttpEntity<String> testHttpEntity() throws UnsupportedEncodingException{
		String body="abc";
		HttpHeaders headers=new HttpHeaders();
		headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt");
		HttpEntity<String> ret=new HttpEntity<String>(body,headers);
		return ret;
	}

chrome为:

IE11为:



也能正常显示出"中国.txt"。
然而将该方案的UTF-8换成GBK,浏览器却不支持了。
如下:

@RequestMapping(value="/test/httpEntity",method=RequestMethod.GET)
	public HttpEntity<String> testHttpEntity() throws UnsupportedEncodingException{
		String body="abc";
		HttpHeaders headers=new HttpHeaders();
		headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","GBK")+".txt");
		HttpEntity<String> ret=new HttpEntity<String>(body,headers);
		return ret;
	}

chrome为:

文件名也全变了。
IE11为:


这里就是说对于URL编码,支持UTF-8,其他的好像还不支持。

解决方案三:
使用最新的解决方案,即filename*=charset'lang'value。charset则是给浏览器指明以什么编码方式来还原中文文件名。
如filename*=UTF-8''value,其中value为原始数据的UTF-8形式的URL编码。
如下:

@RequestMapping(value="/HttpEntity",method=RequestMethod.GET)          
	public HttpEntity<String> testHttpEntity() throws UnsupportedEncodingException{
		HttpHeaders headers=new HttpHeaders();//filename="+URLEncoder.encode("中国","UTF-8")+";
		String body="abc";
		headers.add("Content-Disposition","attachment;filename*=UTF-8''"+URLEncoder.encode("中国","UTF-8")+".txt");
		HttpEntity<String> ret=new HttpEntity<String>(body, headers);
		return ret;
	}

chrome为:


IE11为:


都能够正确显示。
若使用headers.add("Content-Disposition","attachment;filename*=GBK''"+URLEncoder.encode("中国","UTF-8")+".txt"),对此,chrome则是按照GBK方式来还原中文文件名的,所以就会变成


造成乱码。而IE11则直接是



若使用headers.add("Content-disposition","attachment;filename*=GBK''"+URLEncoder.encode("中国","GBK")+".txt")
chrome为:


IE11为:


即IE11仅支持filename*=UTF-8编码形式的。
然后就是headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt;filename*=UTF-8''"+URLEncoder.encode("中国","UTF-8")+".txt");filename和filename*可以组合使用,来解决跨浏览器的问题。

对于上面提出的疑问,还请网友们解答。
  • 大小: 43.1 KB
  • 大小: 49.6 KB
  • 大小: 48.1 KB
  • 大小: 53.6 KB
  • 大小: 50.9 KB
  • 大小: 8.3 KB
  • 大小: 7.9 KB
  • 大小: 9.1 KB
  • 大小: 10.2 KB
  • 大小: 53.4 KB
  • 大小: 7.9 KB
  • 大小: 47.2 KB
  • 大小: 8.1 KB
  • 大小: 64.7 KB
  • 大小: 9.4 KB
分享到:
评论

相关推荐

    文件下载response.setHeader()下载中文文件名乱码问题解决办法.pdf

    文件下载response.setHeader()下载中文文件名乱码问题解决办法 本文主要讨论了文件下载时response.setHeader()下载中文文件名乱码问题的解决办法。该问题是由于 HTTP 消息头中的 Content-Disposition 头字段不正确...

    ( response.setHeader()下载中文文件名乱码

    ( response.setHeader()下载中文文件名乱码问题

    Content-Disposition使用方法和注意事项

    Content-Disposition 是 MIME 协议的一个扩展,用于定义网络传输中的数据应该如何被处理。在Web开发中,它主要用于控制浏览器如何显示或处理响应的资源。本文将深入探讨Content-Disposition的使用方法及其注意事项,...

    ASP.NET 解决下载文件名乱码问题

    在ASP.NET开发中,处理文件下载时经常遇到的一个问题是文件名乱码。这不仅影响用户体验,也降低了应用程序的专业性。本文将深入探讨如何在ASP.NET中解决下载文件名乱码的问题,通过分析代码示例,提供实用的解决方案...

    jsp实现文件下载与中文文件名乱码问题解决

    本文将深入解析如何在JSP中实现文件下载,并解决中文文件名乱码的问题。 首先,我们需要了解HTTP协议在处理文件下载时的角色。当用户请求下载一个文件时,服务器需要设置响应头来指示浏览器如何处理这个响应。在JSP...

    解析如何在PHP下载文件名中解决乱码的问题

    那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:复制代码 代码如下:$filename = “document.txt”;header(‘Content-Type: application/octet-stream’);header...

    Java实现文件下载并解决中文文件名乱码

    ### Java实现文件下载并解决中文文件名乱码 在日常的Web开发中,经常会遇到需要让用户下载文件的需求,尤其是在企业级应用中。然而,在实际操作过程中可能会遇到一个常见问题:当文件名包含中文字符时,下载后的...

    java下载时文件名乱码

    在Java编程中,遇到“java下载时文件名乱码”的问题通常是由于编码不一致或处理不当造成的。在处理文件下载时,尤其是从Web服务器下载带有非ASCII字符的文件名时,这种问题尤为常见。让我们深入探讨这个问题,并提供...

    下载文件个别浏览器文件名乱码解决办法

    代码如下: if (context.Request.UserAgent.ToLower().IndexOf(“msie”, System.StringComparison.Ordinal) &gt; -1)//IE浏览器 { context.Response.AddHeader(“content-disposition”, “filename=” + ...

    Java Web文件下载,解决了使用IE11下载文件时所出现的乱码问题

    本项目针对的一个重要问题就是如何在使用IE11浏览器时避免出现文件名乱码的情况。 首先,我们要理解这个问题的根源。IE11在处理非ASCII字符的文件名时,可能会由于编码不一致导致乱码。这是因为不同的系统和浏览器...

    struts2上传下载 解决中文文件名乱码

    4. **下载时的编码处理**:在下载文件时,需要确保文件名在HTTP响应头中的“Content-Disposition”字段中也使用正确的编码。例如: ```java response.setHeader("Content-Disposition", "attachment; filename=" ...

    Java应用下载文件功能,输出文件名中的中文乱码

    在Java应用中实现文件下载功能时,经常遇到的一个问题是输出文件名中的中文字符会出现乱码。这主要是因为HTTP协议在传输文件名时,默认使用的是ISO-8859-1编码,而中文字符在此编码下无法正确解析,从而导致乱码的...

    下载中文名称出现乱麻解决方案

    因此,解决中文文件名乱码问题对于提升Web应用的质量至关重要。 #### 二、乱码原因分析 文件名出现乱码的根本原因在于编码格式不一致。当服务器端设置的文件名编码格式与客户端浏览器期望的编码格式不符时,就会...

    文件下载,二进制流转换成文件 解决中文名乱码的问题

    在IT领域,尤其是在Web开发中,处理文件下载和解决中文文件名乱码问题是常见的需求之一。本文将深入探讨如何通过二进制流转换为文件来实现文件下载,并着重讲解如何解决中文文件名出现的乱码问题。 ### 文件下载...

    php中强制下载文件的代码(解决了IE下中文文件名乱码问题)

    总的来说,处理IE下的中文文件名乱码问题需要对HTTP协议、浏览器兼容性以及字符串编码有深入的理解。通过适当编码和设置HTTP头部,可以确保文件名在各种环境下都能正确显示。在实际开发中,确保代码的健壮性和兼容性...

    java导出文件文件名处理

    在Web应用中,当服务器向客户端发送文件时,HTTP协议中会包含一个`Content-Disposition`头,用于指定文件的类型和文件名。通常情况下,这个文件名需要被正确编码,以便能够在各种浏览器环境下正常显示。如果编码不当...

Global site tag (gtag.js) - Google Analytics