麻烦的下载对话框的中文文件名处理.

来源:互联网 发布:基于大数据的精准营销 编辑:程序博客网 时间:2024/06/08 09:38

因为不同浏览器对head处理的行为不同,所以下载对话框中的中文文件名比较麻烦.没有统一方法,不要以为你看到的是正确的中文,换个浏览器

或换个版本就不一定正确了.

 

大多数情况下,默认转出UTF-8的字符串是可以的:

 

String str = "这是一个UTF-8格式编码的中文字符串.dat";

如果不是UTF-8,那么转换到 UTF-8的字符串,大多数时候是有效的.

但是同样是UTF-8字符串,IE的不同版本看到的竟然是不同效果.虽然在contentTyep中已经指明 charset=UTF-8,而且从

客户端进看页面编码也是UTF-8,但不同版本的IE却有的乱码有的正常.

 

对于IE而言,全部使用url-encode,所有版本都是正确的.这是网上流行的解决方案,但是.....................

对于IE6,限制文件名大约在150个字符以内,一个中文字符UTF8编码为3个byte,再URLEncode成9个byte,所以对于IE6最多不能超过17个中文.所以这个方法不行.

使用俺8年前用的IE下载的乱码无敌大法,当时在IE6以下的所有版本都绝不乱码.今天测试了一下,IE7,IE8,IE9BATE也坚决不乱,又不会有17个中文字符的限制.方法:

将字符串以GB18030编码转换为byte[],然后将每个byte置的成char进行UTF8编码:

byte[] src = "UTF8字符串".getBytes("GB18030");

byte[] buf = new byte[src.length * 3];

int pos = 0;

for(int i=0;i<src.length;i++){

  char c = (char)src[i] & 0xFF;

  if(c <= 0x007F && c != 0) buf[pos++] = (byte)c;

  else if(c > 0x07FF){

     buf[pos+2] = (byte) (0x80 | ((c >> 0 ) & 0x3F));

     buf[pos+1] = (byte) (0x80 | ((c >> 6 ) & 0x3F));

     buf[pos+0] = (byte) (0xE0 | ((c >> 12 ) & 0x0F));

     pos += 3;

  }

  else{

 

     buf[pos+1] = (byte) (0x80 | ((c >> 0) & 0x3F));

     buf[pos+0] = (byte) (0xC0 | ((c >> 6 ) & 0x1F));

     pos += 2;

  }

}

 

return new String(buf,0,pos,"UTF-8");

绝对无敌....................

 

 

但是对于FF,url-encode肯定是不行了.直接输出UTF-8,基本上测试过的版本都正确.

但是...................................

 

不同的容器行为又不样.因为response.setCharacterEncoding只对实体起作用,对头域不起作用,所以对于头域只能手工处理.

比如tomcat,因为它默认是ISO8859_1,你通过response.setCharacterEncoding可以让它对实体部分的处理按你指定的字符集

处理,但

response.setHeader("Content-Disposition","attachment;filename="+str);

无法控制str按指定的字符集处理,所以只能反向转换把UTF-8转成ISO8859_1:

 

str = new String(str.getBytes("UTF-8"),"ISO8859_1");

response.setHeader("Content-Disposition","attachment;filename="+str);

这样在tomcat输出后,大多数浏览器接收到的 byte[]是UTF-8格式的,能正确处理(IE还是存在版本问题),但这种方案又和容器偶合了.

如果FF不和容器偶合的话,可以进行base64编码,就象IE进行urlencode编码一样.

我KAO,这不是折腾人吗?

 

那么要尽量做到通用,先要判断浏览器:

String agent = request.getHeader("User-Agent");

if(agent == null) xxxx;

agent = agent.toUpperCase();

if(agent.indexOf("MSIE") != -1)   str = URLEncoder.encode(str);

else if(agent.indexOf("FIREFOX") != -1)   str = Base64Encoder.encode(str);

 

else{

............................

}

 

余下的浏览器怎么办呢?经过测试Opera/Chrome都只能解释UTF-8的中文名.所以

 

else{

............................

}将这样:

 

else if(serverTyep.equals("tomcat")){

    str  = new String(str.getBytes("UTF-8"),"ISO8859_1");

 

}

else{

    //其它容器是否要转码看它默认用什么字符集处理.比如resin就不用任何编码,只要是UTF-8格式的就正确

}

 

对于服务端的不兼容,其它平台不一定有这个问题.但是对于客户端的不兼容,任何平台都会有这个问题.要针对不同浏览器做不同的处理.

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 引起嫂嫂裙子顶上去 婶子的哪里又紧水又多 哥哥好凶猛太大要撑坏 老师让学生趴小内内 两个阿姨一起陪我睡觉 朋友妻子来我家洗澡你家茜 老师 主动脱下内内 浪妇杨雪小说全集 同学的妻子在线播放 韩国朋友妻子在线播放 朋友坐牢替他照顾妻子在线播放 比我老婆还要正在线播放 朋友的妻子20在线播放 寂寞的妻子手机在线 朋友出差替他照顾妻子在线播放 偷朋友妻子在线播放 搞兄弟母亲中文字在线播放 隔壁的日本妻子1中文字 年轻的母亲5d整部中文字 老师强入我体内 嫂嫂 的房门没关紧 共享妻子第3季 小石玩妻子第三部 朋友母亲的味道中文版 互换朋友妻子3换 母亲的朋友2集中文免费观看 领导出差他老婆留我过夜 厨房偷上朋友妻全文阅读答案 被老公朋友强入bd 和领导回家睡了他老婆 老公在偷吃别人我在家吃他老爹 送领导回家强睡他老婆 我在老公的眼皮底下偷吃 快递员在我家要了我 30岁军嫂身体好软 当着女朋友的面睡他朋友视频 偷朋友的妻子电影中国字 老公朋友下厨房要了我 朋友打麻将我在楼上 下厨房里边做菜边啪 相隔不到5公尺偷捅妻子朋友