文章插图
Web 开发过程中,相信大家都遇到过附件下载的场景,其中,各浏览器下载后的文件名中文乱码问题或许一度让你苦恼不已 。
网上搜索一下,大部分都是通过Request Headers中的UserAgent字段来判断浏览器类型,根据不同的浏览器做不同的处理,类似下面的代码:
// MicroSoft Browserif (agent.contains("msie") || agent.contains("trident") || agent.contains("edge")) {// filename 特殊处理}// firefoxelse if (agent.contains("firefox")) {// filename 特殊处理}// safarielse if (agent.contains("safari")) {// filename 特殊处理}// Chromeelse if (agent.contains("chrome")) {// filename 特殊处理}// 其他else{ // filename 特殊处理}//最后把特殊处理后的文件名放到head里response.setHeader("Content-Disposition","attachment;fileName=" + filename);不过,这样的代码看起来很魔幻,为什么每个浏览器的处理方式都不一样?难道每次新出一个浏览器都要做兼容吗?就没有一个统一标准来约束一下这帮浏览器吗?
带着这个疑惑,我翻阅了 RFC 文档,最终得出了一个优雅的解决方案:
// percentEncodedFileName 为百分号编码后的文件名response.setHeader("Content-disposition","attachment;filename=" + percentEncodedFileName +";filename*=utf-8''" + percentEncodedFileName);经过测试,这段响应头可以兼容市面上所有主流浏览器,由于是 HTTP 协议范畴,所以语言无关 。只要按这个规则设置响应头,就能一劳永逸地解决恼人的附件名中文乱码问题 。
接下来课代表带大家抽丝剥茧,通过阅读 RFC 文档,还原一下这个响应头的产出过程 。
1. Content-Disposition一切要从 RFC 6266 开始,在这份文档中,介绍了Content-Disposition响应头,其实它并不属于HTTP标准,但是因为使用广泛,所以在该文档中进行了约束 。它的语法格式如下:
content-disposition = "Content-Disposition" ":"disposition-type *( ";" disposition-parm )disposition-type= "inline" | "attachment" | disp-ext-type; case-insensitivedisp-ext-type= tokendisposition-parm= filename-parm | disp-ext-parmfilename-parm= "filename" "=" value| "filename*" "=" ext-value其中的disposition-type有两种:
inline 代表默认处理,一般会在页面展示attachment 代表应该被保存到本地,需要配合设置filename或filename*注意到disposition-parm中的filename和filename*,文档规定:这里的信息可以用于保存的文件名 。
它俩的区别在于,filename 的 value 不进行编码,而filename*遵从 RFC 5987中定义的编码规则:
Producers MUST use either the "UTF-8" ([RFC3629]) or the "ISO-8859-1" ([ISO-8859-1]) character set.由于filename*是后来才定义的,许多老的浏览器并不支持,所以文档规定,当二者同时出现在头字段中时,需要采用filename*,忽略filename 。
至此,响应头的骨架已经呼之欲出了,摘录 [RFC 6266] 中的示例如下:
Content-Disposition: attachment;filename="EURO rates";filename*=utf-8''%e2%82%ac%20rates这里对filename*=utf-8”%e2%82%ac%20rates做一下说明,这个写法乍一看可能会觉得很奇怪,它其实是用单引号作为分隔符,将等号右边分成了三部分:第一部分是字符集(utf-8),中间部分是语言(未填写),最后的%e2%82%ac%20rates代表了实际值 。对于这部分的组成,在RFC 2231.section 4 中有详细说明:
A single quote is used toseparate the character set, language, and actual value information inthe parameter value string, and an percent sign is used to flagoctets encoded in hexadecimal.2.PercentEncodePercentEncode 又叫 Percent-encoding 或 URL encoding.
正如前文所述,filename*遵守的是[RFC 5987] 中定义的编码规则,在[RFC 5987] 3.2中定义了必须支持的字符集:
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- 游戏地图制作方法 手机游戏地图制作软件
- 性能完爆当红旗舰的二手手机如何选 性价比最高的二手旗舰手机
- 2000长辈用性价比高的手机 2000左右高性价比手机老人用
- 这3款智能手机 这三款手机
- 如何解决手机卡的问题 怎么办才能解决手机卡的问题
- 手机卡顿反应慢 手机卡顿反应慢怎么解决
- 购买手机时配置如何选择 买手机怎么选择配置
- 你的手机屏幕究竟什么水平 手机屏幕什么样
- 2021买手机内存多大合适 2021年手机内存多大合适
- 2022年买手机别只盯着旗舰,这十款性价比超高,是最合适你的选择