при загрузке имена файлов с неанглоязычных языков неправильно отображаются в загруженном файле


Когда я пытаюсь загрузить файл, имя которого содержит символы из таких языков, как китайский, японский и т. Д...... не ascii... загруженное имя файла искажено. Как это исправить.

Я попытался поместить charset=UTF-8 в свойство заголовка типа содержимого, но безуспешно. Пожалуйста, помогите. Код ниже.

Заголовок ("Управление кэшем:");//оставьте пустым, чтобы избежать ошибок IE

Заголовок ("Pragma:");//оставьте пустым, чтобы избежать ошибок IE

Заголовок ("Тип содержимого: приложение/октет-поток");

Заголовок ("Содержимое-Расположение: вложение; имя файла=\"".$имя_экзамена."\"");

Заголовок ("Длина содержимого:".(строка)(размер файла ($filestring)));

Сон(1);

Fpassthru($fdl);

Author: skaffman, 2010-04-05

2 answers

К сожалению, в настоящее время не существует единого решения, которое работало бы со всеми браузерами. Существует по крайней мере три "более очевидных" подхода к этой проблеме.

А) Content-type: application/octet-stream; charset=utf-8 + filename=<utf8 byte sequence>
например, filename=Москва.txt
Это нарушение стандартов, но firefox правильно отображает имя. То есть нет.

Б) 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/


Редактировать: Когда я сказал, что единого решения не существует, я имел в виду заголовок ('...'). Но есть что-то вроде обходного пути.
Когда нет подходящего заголовка filename=xyz, браузеры используют базовое имя части пути URL. Т.е. для <a href="test.php/lala.txt"> как firefox, так и IE предлагают lalala.txt в качестве имени файла.
Вы можете добавить дополнительные компоненты пути после того, как фактическая путь к php-скрипт (при использовании файла 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, так и Т.Е. предложите "правильное" имя.
Вы даже можете объединить его с отправкой имени в соответствии с rfc 2231. Вот почему я также вставил moskwa в ссылку. Это будет идентификатор, который скрипт использует для поиска файла, который он должен отправить. IE игнорирует информацию filename*=... и по-прежнему использует часть URL-адреса с базовым именем, чтобы предложить имя. Это означает, что для firefox (и любого другого клиента, поддерживающего rfc 2231) часть после идентификатора бессмысленна*, но для 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'];
}

*) Это немного похоже на переполнение стека. Ссылка на этот вопрос показана как

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

Важной частью является идентификатор 2578349

 11
Author: VolkerK, 2010-04-05 14:59:38

Я думаю, что если вы попытаетесь добавить другую кодировку, это исправит вашу проблему.

Если я все еще думаю, что вам нужно установить языковые файлы с компакт-диска XP в вашу систему, потому что, если система не сможет найти правильные символы, она добавит нечетные.

У меня была такая проблема с арабским языком, но я обнаружил, что не скопировал все языковые файлы в свою систему.

Надеюсь, это поможет вам.

 0
Author: Saleh, 2010-04-05 12:59:22