php - 从非英语语言下载文件名时未正确显示在下载的文件上

标签 php download

当我试图下载一个文件,其名称包含中文、日文等语言的字符时……非 ascii……下载的文件名是乱码。如何改正。

我尝试将 charset=UTF-8 放入 Content-type header 属性中,但没有成功。代码如下。

header("Cache-Control: ");// leave blank to avoid IE errors

header("Pragma: ");// leave blank to avoid IE errors

header("Content-type: application/octet-stream");

header("Content-Disposition: attachment; filename=\"".$instance_name."\"");

header("Content-length:".(string)(filesize($fileString)));

sleep(1);

fpassthru($fdl);

最佳答案

遗憾的是,目前没有一种解决方案适用于所有浏览器。 至少有三种“更明显”的方法可以解决这个问题。

a) Content-type: application/octet-stream; charset=utf-8 + filename=<utf8 byte sequence>
例如filename=Москва.txt
这违反了标准,但 firefox 正确显示了名称。 IE 没有。

b) Content-type: application/octet-stream; charset=utf-8 + filename=<urlencode(utf8 byte sequence)>
例如filename=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
这适用于 IE,但不适用于 Firefox。

c) 提供在 rfc 2231 中指定的名称
例如 filename*=UTF-8''%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
Firefox 再次支持这一点,而 IE 不支持。

要获得更全面的比较,请参阅 http://greenbytes.de/tech/tc2231/


编辑:当我说没有单一的解决方案时,我的意思是通过 header('...')。但是有一些解决方法。
当没有可用的 filename=xyz header 时,浏览器使用 url 路径部分的基本名称。 IE。对于 <a href="test.php/lala.txt"> firefox 和 IE 都提示 lalala.txt作为文件名。
可以在您的 php 脚本的实际路径之后附加额外的路径组件(使用 apache 的 httpd 时请参阅 http://httpd.apache.org/docs/2.1/mod/core.html#acceptpathinfo)。
例如。如果您的文档根目录中有一个文件 test.php 并将其请求为 http://localhost/test.php/x/y/z变量 $_SERVER['PATH_INFO']将包含 /x/y/z .
现在,如果你放一个像

这样的链接
<a
  href="/test.php/download/moskwa/&#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430;"
>
  &#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430;
</a>

在您的文档中,您可以获取 download/moskwa/...部分并开始下载文件。在不发送任何文件名=...信息的情况下,firefox 和 IE 都会建议“正确的”名称。
您甚至可以将它与根据 rfc 2231 发送名称结合起来。这就是为什么我也放了 moskwa 的原因。进入链接。那将是脚本用来查找它应该发送的文件的 id。 IE 忽略 filename*=...信息并仍然使用 url 的基本名称部分来建议名称。这意味着对于 firefox(以及任何其他支持 rfc 2231 的客户端)id 之后的部分没有意义*但对于 IE(以及其他不支持 rfc 2231 的客户端)它将用于名称建议。
独立示例:

<?php // test.php
$files = array(
  'moskwa'=>array(
    'htmlentities'=>'&#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430;',
    'content'=>'55° 45′ N, 37° 37′ O'
  ),
  'athen'=>array(
    'htmlentities'=>'&#x391;&#x3b8;&#x3ae;&#x3bd;&#x3b1;',
    'content'=>'37° 59′ N, 23° 44′ O'
  )
);


$fileid = null;
if ( isset($_SERVER['PATH_INFO']) && preg_match('!^/download/([^/]+)!', $_SERVER['PATH_INFO'], $m) ) {
  $fileid = $m[1];
}

if ( is_null($fileid) ) {
  foreach($files as $fileid=>$bar) {
    printf(
      '<a href="./test.php/download/%s/%s.txt">%s</a><br />', 
      $fileid, $bar['htmlentities'], $bar['htmlentities']
    );
  }  
}
else if ( !isset($files[$fileid]) ) {
  echo 'no such file';
}
else {
  $f = $files[$fileid];
  $utf8name = mb_convert_encoding($f['htmlentities'], 'utf-8', 'HTML-ENTITIES');
  $utf8name = urlencode($utf8name);

  header("Content-type: text/plain");
  header("Content-Disposition: attachment; filename*=UTF-8''$utf8name.txt");
  header("Content-length: " . strlen($f['content']));
  echo $f['content'];
}

*) 这有点像 Stack Overflow 上的此处。此问题的链接显示为

http://stackoverflow.com/questions/2578349/while-downloading-filenames-from-non-english-languages-are-not-getting-displayed

但它也适用于

http://stackoverflow.com/questions/2578349/mary-had-a-little-lamb

重要的部分是id 2578349

关于php - 从非英语语言下载文件名时未正确显示在下载的文件上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2578349/

相关文章:

php - Laravel Mailable 不更新代码

php - 上传时压缩图像文件大小?

php - 让ajax更新mySQL行结果中相应的div

security - 如何在网站上安全地提供视频

php 用图像替换数据库结果

php - laravel5.1 使用 Eloquent 检索不直接相关的嵌套属性

asp.net-mvc - 如何从服务器下载文件到客户端?

android - 使用 Cordova FileTransfer 将文件保存到公共(public)目录

google-chrome - 如何防止谷歌浏览器阻止我的安装程序包

asp.net - 文件下载不适用于 IE7