连2011年发布的国际标准都没能正确支持的浏览器,也是够丢人的……

描述此 Pull Request 的变更

优化 部分不遵守国际标准的常见浏览器的相关特殊处理

描述变更理由

之前的PR !1212:【轻量级 PR】:修复手机端下载文件,文件名为forum.php的问题 发现并部分修复了一个关于某些手机浏览器下载附件没文件名的问题,覆盖了我之前提交的!747:修复 部分场景下下载文件名出错及不符合标准的问题 的部分行为。
由于按此方法修复后就不再遵循国际标准,有出问题的可能性,我这边就核实了一下。
结果……发现这坑真的挺大的。

为什么一定要遵守国际标准

遵循国际标准是为了适配主流浏览器都已经认可的一套通行的标准,而不用再去考虑具体的每种浏览器的解析方式,如果不再遵循这一标准,问题将会变得非常麻烦。

光是编码就有如下的这么多种:

  1. 直接传送iso-8859-1编码
  2. 直接传送UTF-8编码
  3. 传送RFC2047编码(常用于邮件,走base64)=?UTF8?B?xxxxxxx
  4. 传送百分号编码(rawurlencode)
  5. 传送RFC2231(存疑,找不到相关资料)

靠直接传输探测编码的话,按标准是只能传iso-8859-1的(甚至是默认),UTF-8行为为部分浏览器自行扩展且基于编码探测,编码还有重叠,一旦猜错直接乱码。靠编码可以解决这种问题。
但无论是以上哪种都无法完全兼容所有浏览器,总是有翻车的。
RFC中给出的推荐做法为:要么用最新国际标准,要么把字符限制到ASCII范围内。

具体到移动端,也只有跟国际标准才能让Chrome Firefox Safari等都乖乖听话。

那些不遵守国际标准的常见浏览器

麻烦事就在于一部分在国内很常见的浏览器它不遵守国际标准。
RFC6266可是2011年出的,都10年了啊,在座的各位移动端浏览器都没它久,没有道理啊。

我把国内市场占有率靠前的浏览器基本全测了一遍。
经过实测,发现了如下的问题:

  • UC和夸克浏览器我这边实测是不存在显示成forum.php的情况的,但存在另一个问题:它适配了最新编码,却不按最新编码的要求屏蔽另一种,而是把2个全给解析了,导致文件名是重复显示两次的。
  • 百度(浏览器),搜狗浏览器,猎豹浏览器的行为是一样的,只要里面多出一点它看不懂的内容它就不解析文件名,显示成forum.php,哪怕我重新调换了顺序都不好使。
  • 360浏览器,QQ浏览器,微信内置浏览器,华为浏览器等厂商很好的遵循了国际标准,跟Chrome,Firefox,Safari,Edge,Opera等国际浏览器一样,可以正确解析文件名。

解决办法

经过多次反复尝试,最终发现想要用一套标准,同时兼容这些行为怪异的浏览器和正常的浏览器的难度太大了(原因见上一段)。

最终只好通过单独处理的方式,专门为上述浏览器设计了一个黑名单,检测到如上所述的问题浏览器,就临时屏蔽掉国际标准的部分,降级到传统方式。实测可以解决问题。
(猎豹浏览器最后经考虑没有加入列表,因为经调查它的市场占有率实在是太低了)

对不向前兼容或涉及安全性变更的特殊说明

关联 Issue