有什么方法可以让Android的默认浏览器识别"Content-Disposition:attachment"下载中的非ASCII文件名?

kij*_*jin 11 php filenames android utf-8 content-disposition

首先,我很确定这不是重复,因为我已经在StackOverflow和其他地方研究了这个主题很长一段时间.已经提出了类似的问题,但没有人得到满意的回答.

过去的相关(但不完全相同)问题:

我也完全了解使用HTTP标头中的文件名完全没必要mod_rewrite技巧.但我们假设这不是一个选择.


大多数现代浏览器(IE9 +,Firefox,Chrome)在下载名称中包含非ASCII字符的文件时都支持RFC2231/5987.在这些情况下,以下PHP代码就像一个魅力:

header("Content-Disposition: attachment; " .
       "filename*=UTF-8''" . rawurlencode($filename));
Run Code Online (Sandbox Code Playgroud)

IE <= 8不了解RFC2231/5987,但以下代码大部分时间都有效.由于每个浏览器都试图在某种程度上模拟IE,这也适用于许多其他浏览器,例如Firefox.

header("Content-Disposition: attachment; " .
       'filename="' . rawurlencode($filename) . '"');
Run Code Online (Sandbox Code Playgroud)

同时,Chrome <11和Safari <6似乎更喜欢以下内容,尽管它将非ASCII字符直接放在标题中.

header("Content-Disposition: attachment; filename=" . $filename);
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.


但是,当谈到Android的默认浏览器应用程序时,一切都崩溃了.(到目前为止,我已经在姜饼,冰淇淋三明治和果冻豆中进行了测试.)

如果您给它标准的RFC2231/5987处理,默认浏览器完全忽略它并尝试从URL的最后部分猜测文件名.

如果你给它通常的非标准(IE <= 8)处理,默认浏览器会尝试将文件名解释为ISO-8859-1,导致无法理解的字符混乱,或者它会以静默方式丢弃所有非ASCII字符.版本之间的确切行为有所不同,但无论如何,很明显Android的默认浏览器也不支持rawurlencode()格式.

如果将原始文件名放在标题中,则会发生同样的情况.

这通常不是第三方浏览器的问题,例如Firefox for Android,Dolphin Browser和Boat Browser.默认浏览器应用程序是唯一一直无法理解UTF-8文件名的应用程序.


也许这最终在Android的最新版本中得到了修复,或者可能会在下一个版本中修复.但这不是我的问题.我需要这个在现有设备中工作,并且仍然有数百万个Gingerbread和ICS设备.

我已经阅读了错误报告,我已经阅读了投诉,我已经阅读了很多关于这个问题的内容.到目前为止,我一直无法找到任何实际有效的编码方案.

如果有人知道如何**标头中编码非ASCII文件名**(例如????????????.jpg)并让Android默认浏览器识别它,请分享!我不在乎它是多么hacky或非标准.我不关心是否需要针对每个Android版本进行自定义. Content-Disposition

更新

不幸的是,到目前为止,我还没有收到任何能够解决上述问题的答案.所以赏金到期无人认领.请不要回答,除非您确实知道如何以ICS之前的Android浏览器识别的方式编码非欧洲混合语言文件名,或者您有确凿的证据表明这是不可能的.

App*_*234 3

URLUtil.java负责guessFileName哪些调用parseContentDisposition使用此正则表达式"attachment;\\\\s*filename\\\\s*=\\\\s*(\\"?)([^\\"]*)\\\\1\\\\s*$"

\n\n

根据 Content-Disposition 标头获取文件的文件名。

\n\n

下面的源代码尝试复制 parseContentDisposition 功能,在我测试时工作正常。例如它返回 \xd1\x84\xd0\xb0\xd0\xb9\xd0\xbb\xd0\xb0\xed\x8c\x8c\xec\x9d\xbc\xe3\x83\x95\xe3\x82\xa1\xe3\ x82\xa4\xe3\x83\xab\xe5\x90\x8d.jpg。

\n\n
import java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\npublic class HelloWorld{\n\n     public static void main(String []args){\n     String contentDisposition = "Content-Disposition: attachment; " + " filename=" +"\\"\xd1\x84\xd0\xb0\xd0\xb9\xd0\xbb\xd0\xb0\xed\x8c\x8c\xec\x9d\xbc\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe5\x90\x8d.jpg\\"";     \n     Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile("attachment;\\\\s*filename\\\\s*=\\\\s*(\\"?)([^\\"]*)\\\\1\\\\s*$",Pattern.CASE_INSENSITIVE);\n        try {\n            Matcher m = CONTENT_DISPOSITION_PATTERN.matcher(contentDisposition);\n            if (m.find()) {\n                System.out.println("Result: " + m.group(2));\n            }\n        } catch (IllegalStateException ex) {\n             // This function is defined as returning null when it can\'t parse the header\n        }\n\n     }\n}\n
Run Code Online (Sandbox Code Playgroud)\n