作者 muzuiget
 发布 2013-03-13 19:23
 标签 redisposition
Firefox 下载文件名乱码问题由来已久,偶然一两次还可以手动改名,批量下载时简直要亲命,最终我还是写了个通用型的扩展来解决。
下载安装
名字叫 ReDisposition,已经上传到 AMO,并且通过了初步审核。源代码 在 GitHub 上。
免重启扩展,目前体积不到 20K,并且提供一个工具栏按钮以便无痛切换。
 
但是这个扩展不是万能药,不要指望安装上自动解决所有问题,你必须继续阅读下面的技术分析。
乱码问题
这个问题多被 Linux/Mac 用户抱怨,但不是 Firefox 独有的,其它浏览器也一样。不是外国人看不起天朝人而迟迟不解决,因为做错的不是浏览器,而是服务器。
这三篇文章已经详细分析过原因和给出一些临时解决办法:
 Firefox 下载保存时中文文件名乱码之谜
 Firefox 下载保存时中文文件名乱码之谜底
 解决迅雷离线各种恼人问题
长篇大论估计急于找解决方法的仁兄估计没什么耐性看,我这里再简单说一下。
乱码原因
一般情况下,文件名是浏览器从 url 推测出来的,但是某些服务器可能要进行下载统计或者用户认证,url 是像 /download?fid=1234 这样的形式,所以会让浏览器使用了 download 这个无意义名字,但是服务器可以在 http 协议头里定义一个叫 Content-Disposition 的字段来指定文件名,于是又多了一个需要顾及编码问题的地方。
一般服务器会返回的是
Content-Disposition: attachment; filename="foo.bar";
 
浏览器会对 foo.bar 部分用了 UTF-8 解码,如果服务器这里使用了 GBK 的话,就会解码失败。于是浏览器会做些兼容,尝试其它地方配置里定义过的编码,大概有:
 下载引用页的网页编码 
浏览器字体设置中的编码 
操作系统的编码 
之所以在简体中文的 Windows 里没这个问题,因为默认的操作系统编码就是 GBK,所以最后还是蒙对了。而繁体中文的 Windows 的系统编码是 BIG5,Linux/Mac 的系统编码都是 UTF-8,所以结果还是乱码。
如果还是失败怎么办?那浏览器可能直接作为乱码显示出来,或者忽略掉这个字段,回头在 url 里推测。我没看出固定规律,Firefox 多数会是前者,Chrome 多数会是后者。
解决方法
有 4 种方法
第 1 种
因为问题出在服务器,所以根本解决方法是联系网站的开发者,让他们修改,按标准来做,默认使用 UTF-8。不过人家多数不会鸟你的,只要领导在的 Windows 上的 IE 没问题就行了,提高兼容性能涨工资吗?就不用加班了吗?出事你负责吗?那还改毛?
第 2 种
所以只好退回客户端这边解决,可以修改上面 3 个地方的备选编码,网上的流传方法都是如此,但是可能带来的副作用就是本来没问题的网站又有问题了,只是拆东墙补西墙,问题还是没解决。
第 3 种
可以联系浏览器的开发者,让他们专门为这个字段加一个备选编码配置,我已经给 Firefox 提 bug 了,不知道何年何月得偿所望,不过走做路过不要错过请顺手 vote 一下。
第 4 种
那么只好折中一下,也就是这个扩展所做的,干脆把该字段先改成指定编码的形式,再传给下载对话框。
也就是转换成:
Content-Disposition: attachment; filename*=GBK''foo.bar;
 
这里的 GBK 也就是你在工具栏按钮的菜单所指定的,GB18030 也就是 GBK 的超集。
所以如果你发现某个网站下载出现乱码,激活按钮并选一个编码然后再重新下载就行了。临时启用,搞定好后再点按钮禁用就行了。
具体编码可以在扩展首选项里配置,编码间用英文逗号分隔,默认是 GB18030, BIG5。
开发者的选择
对 Content-Disposition 的用法,这里各浏览器的 测试用例和结果,看完后好绝望。尤其是那个极品的奇葩 IE,都 IE 9 了对指定编码形式还不完善。
标准都有好几个,而且浏览器就更多了,但最常见都是上面说的一般和指定编码两种形式。我觉得最简单的兼容方案就是,在服务端先判断浏览器的 User-Agent,不管操作系统:
 对 IE, 就返回一般形式,用 GBK 编码,放弃支持其它语言 Windows 的 IE 用户。 
对非 IE 的,就返回指定编码的形式,现代先进浏览器都支持。 
inline 模式
一个附加小功能,对于像文本和图像这样的文件,某些网站可能也会加那个字段让浏览器提示下载的,但你想直接显示在浏览器里,只要那个字段改成 inline 就行了。
可以用 这个图片 测试,用了 Google 的图片代理,点击会弹出保存为 p.txt 的提示,但是切换到 inline 模式后,再点击就会在浏览器里直接显示了。
当然,对于 Firefox 不支持直接打开的文件,例如压缩包,还是会直接提示保存的。
总结
你或许说像 Adblock Plus 那样弄个白名单机制,对有乱码出现的网站自动处理,不用点按钮就好了。我一开始也打算这么做的。因为我发现百度网盘也是乱码的,于是修改那个迅雷离线的扩展,添加百度网盘支持,但让我崩溃的是,同一个下载列表页面里,居然有些文件使用 GBK,有些文件使用 UTF-8,而且无法通过 url 判断。所以我就死了这条心了,改成用工具栏按钮临时启用。
当我完成这个扩展时,才想起,直接在下载对话框里加个转换按钮直接转不就好了吗?省得还要取消对话框,激活扩展按钮,然后重新点下载,这个还是以后再说吧。

解决 Firefox 下载文件名乱码扩展 ReDisposition的更多相关文章

  1. 解决wget下载文件名乱码的一些方法

    在下载用apache或者nginx做的索引目录时,遇到文件名乱码问题.搜索了不少资料,尝试了好几种方案,大家可以结合使用. 一般情况下加上–restrict-file-names=nocontrol参 ...

  2. Firefox下载附件乱码的解决办法

    通过在http的header里设置fileName下载附件时,中文文件名通过chrome浏览器下载时正常,通过firefox下载时为乱码: 原来的Java代码: response.addHeader( ...

  3. 【.net】在ASP.NET中,IE与Firefox下载文件名中带中文汉字的文件,文件名乱码的问题

    #问题:客户端为ie或Firefox,服务端为asp.net时,下载文件名中包含中文汉字时,下载下来的文件的文件名是乱码: #解决方案: 示例代码:下载名称中带汉字的文件: public void P ...

  4. C#导出Excel文件Firefox中文件名乱码

    首先说明下:我的解决方法不一定适用于其他遇到该问题的人,因为情况多种多样,适合我的方法不一定适合别人,就像我在遇到问题时查到别人的解决方案放到我的代码里却不管用,所以这个方法仅供参考 这两天做了一个导 ...

  5. Linux 解决 firefox 中文页面乱码问题

    1.由于 firefox 默认是允许网页自己选择字体,在 Linux 上便会出现部分网站的乱码情况.因此可以取消允许页面自己选择字体这个选项便能解决部分乱码情况.

  6. 解决PHP在IE浏览器下载文件,中文文件名乱码问题

    前提:我们网站所有文件全部使用的是UTF-8 NO BOM的编码方式 1.找测试重现.360浏览器下载的呵呵,果然文件名是乱码.再请测试在ie浏览器下测试.IE9,8,7也全部是乱码.查看编码就是UT ...

  7. 利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码

    利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码 2014-07-31 12:53 1047人阅读 评论(0) 收藏  ...

  8. C#中解决Response.AddHeader("Content-Disposition", "attachment; filename=" + filename)下载文件时文件名乱码的问题

    问题:下载文件时文件名乱码怎么解决? 在C#写后台代码过程中,经常遇到下载文件出现文件名乱码的问题,在网上找了很多方法,总是存在浏览器不兼容的问题,当IE浏览器不乱码时,火狐浏览器就会乱码,后来经过反 ...

  9. 在ASP.NET中,IE与Firefox下载文件带汉字名时乱码的解决方法

    解决办法: HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Buffer = true; HttpContext. ...

随机推荐

  1. ***PHP基于H5的微信支付开发详解(CI框架)

    这次总结一下用户在微信内打开网页时,可以调用微信支付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能.当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现代码可 ...

  2. 开始写博客,学习Linq(3)

    为什么需要Linq?(摘自原文) 读者会发现LINQ着眼于解决编程语言和数据库之间广发存在的不统一问题. 1.常见的问题,使用.NET Framework Class Library(FCL)提供了A ...

  3. c++ primer 笔记 (三)

    标准库类型string 和 vector ,分别定义了大小可变的字符串和集合.                 bitset,提供了一个抽象方法来操作位的集合.提供更方便的处理位的方式(相对于整型值上 ...

  4. python中执行shell的两种方法总结

    这篇文章主要介绍了python中执行shell的两种方法,有两种方法可以在Python中执行SHELL程序,方法一是使用Python的commands包,方法二则是使用subprocess包,这两个包 ...

  5. Cube Stack

    Cube Stack 有一点lazy思想,设三个数组cnt代表它以下的有多少个元素(直到栈底),top[x]代表x所在栈的栈顶元素,dad[x]代表x所在栈的栈底元素,先寻找父亲,然后递归更新累加cn ...

  6. Android入门笔记

    Android项目的目录结构(Eclipse版) src:项目源代码文件夹 R.java:存放项目中所有资源文件的资源id,永远不要修改 Android.jar:Android的jar包,导入此包方可 ...

  7. C# 遍历控件 示例

    foreach(Control c in tabControl1.TabPages)//这个循环的意思是说,遍历tabControl1中所有的TabPages,TabPages是包含在tabContr ...

  8. TFT LCD显示原理详解

    <什么是液晶> 我们一般认为物体有三态:固态.液态.气态,其实这只是针对水而言,有一些有机化和物 还有介于固态和液态中间的状态 就是液晶态,如下图(一):                 ...

  9. [NOIp2015提高组]信息传递

    OJ题号:洛谷2661 思路:求最小环.DFS+记忆化. #include<cstdio> #include<cstring> #include<algorithm> ...

  10. linux中内存超出后可以这样

    http://www.cnblogs.com/hongten/archive/2012/11/16/java_PermGen_space.html