欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

Content-Disposition非英文下的处理注解

程序员文章站 2022-05-17 11:22:39
...

RFC标准就是个屁

RFC标准就是个屁啊。各种行为就没个统一的,根源就是早期协议对header本身的编码没有做规定,而现实中,浏览器有面临这种需求 于是就纷纷乱操了。。

就是个抱怨文 记录下免得自己忘记? 主要的内容 这篇文章都讲了 所以 这边给个注解,

主要的意思 大家还是看原文 我来说下目前 RFC 5987 正式规定了 HTTP Header 中多语言编码的处理方式,规定是这样的:

parameter*=charset'lang'value

其中 value 应根据 RFC 3986 Section 2.1 使用百分号进行编码,并且规定浏览器至少应该支持 ASCII 和 UTF-8

2011年 RFC 6266 发布,正式将 Content-Disposition 纳入 HTTP 标准,并再次强调了 RFC 5987 中多语言编码的方法,还给出了一个范例用于解决向后兼容的问题

但是由于HTTP 1.1 草案中建议的使用 RFC 2047 来进行多语言编码的特性从未被主流浏览器支持过,我们把lang那个置空,之后对应到Content-Disposition就是这样的

filename*=utf-8''encoded_text

其中,encoded_text指的是将 UTF-8 编码的原始文件名按照 RFC 3986 进行百分号 urlencode 后得到的( PHP 中对应 rawurlencode() 函数,rawurlencode会把空格编码成%20,而PHP的urlencode会把空格编码为+号 这个是不对的)。

所以 原文博主给出了一个RFC推荐的方式,测试下来目前也确实安好

Content-Disposition: attachment;
                     filename="$encoded_fname";
                     filename*=utf-8''$encoded_fname

但是,等等,这还没完 还是那个rawurlencode的问题。使用这种方式WebKit和Gecko核心的浏览器都没有问题 但是IE又来作了 从IE7~IE11 %20 还是显示成 %20(就是空格被编码以后)? 你让强迫症用户咋办啊。尝试不进行编码,Firefox就会把空格后面的字给丢了,Chrome依然可以正常显示。

虽然上面这张hack很优雅的能显示汉字了,但是为了强迫症用户考虑 还得根据IE这个奇葩来处理一下 我现在使用这样的代码

header('Content-type: application/octet-stream');
$fileName = rawurlencode($info['name']);
//IE不能正确的处理空格 IE11也不行 还是避免不了hack IE6必须附加一个正确的英文扩展名
if (strpos($_SERVER["HTTP_USER_AGENT"],'Trident') !== false) $fileName = str_replace('%20','_',$fileName);
header(sprintf("Content-Disposition: attachment; filename=%1\$s; filename*=%2\$s''%1\$s",$fileName,(defined("CHARSET"))?CHARSET:'UTF-8'));

我把%20替换成了下划线 当然直接替换成空格也是可以的。还是免不得对IE这个奇葩做一些特殊处理 但是已经比网上流传的那些trick更加符合标准多了。我喜欢这种方式。

补充一句:DZ的那个做法也是不恰当的。