2010-04-05 18 views
5

Cuando intento descargar un archivo cuyo nombre tiene caracteres de idiomas como chino japonés, etc. ...... no ascii ... el archivo descargado el nombre del archivo está distorsionado. Cómo rectificarloal descargar nombres de archivos de idiomas no ingleses no se muestran correctamente en el archivo descargado

He intentado poner charset = UTF-8 en la propiedad del encabezado Content-type, pero no tuve éxito. Por favor ayuda. Código a continuación.

header ("Cache-Control: "); // dejar en blanco para evitar errores de IE

de cabecera (" Pragma: "); // dejar en blanco para evitar errores de IE

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

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

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

sleep (1);

fpassthru ($ fdl);

+1

Por favor, añadir un poco de información básica. ¿De dónde viene '$ fileString'? ¿En qué codificación está? –

+0

la variable se recogen de la base de datos y se usan. both instance_name y filestring – pks83

Respuesta

9

Lamentablemente, actualmente no existe una única solución que funcione con todos los navegadores. Existen al menos tres enfoques "más obvios" para el problema.

una) Content-type: application/octet-stream; charset=utf-8 + filename=<utf8 byte sequence>
por ejemplo filename=Москва.txt
Esto es una violación de las normas pero firefox muestra el nombre correctamente. IE no.

b) Content-type: application/octet-stream; charset=utf-8 + filename=<urlencode(utf8 byte sequence)>
e.g. filename=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
Esto funciona con IE pero no con Firefox.

c) proporcionar el nombre como se especifica en rfc 2231
por ejemplo filename*=UTF-8''%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
De nuevo Firefox apoya esta, IE no lo hace.

para una comparación más completa ver http://greenbytes.de/tech/tc2231/


edición: Cuando dije que no hay una solución única, me refería a través de cabecera ('...'). Pero hay algo de trabajo alrededor.
Cuando no hay un nombre de archivo utilizable = xyz los navegadores de encabezado usan el nombre base de la parte de la ruta de la url. Es decir. para <a href="test.php/lala.txt"> tanto Firefox como IE sugieren lalala.txt como nombre de archivo.
Usted puede agregar componentes de ruta adicionales después de la ruta real a su script php (cuando se utiliza el httpd de apache, vea http://httpd.apache.org/docs/2.1/mod/core.html#acceptpathinfo).
P. ej. si tiene un archivo test.php en su documento raíz y lo solicita como http://localhost/test.php/x/y/z, la variable $_SERVER['PATH_INFO'] contendrá /x/y/z.
Ahora, si pones un enlace como

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

en el documento se puede recuperar la parte download/moskwa/... e iniciar la descarga del archivo. Sin enviar ningún nombre de archivo = ... información, tanto Firefox como IE sugieren el nombre "correcto".
Incluso puede combinarlo con enviar el nombre de acuerdo con rfc 2231. Es por eso que también puse moskwa en el enlace. Esa sería la identificación que usa el script para encontrar el archivo que se supone que debe enviar. El IE ignora la información filename*=... y aún utiliza la parte del nombre base de la url para sugerir un nombre. Eso significa que para Firefox (y cualquier otro cliente que admita rfc 2231) la parte posterior a la id no tiene sentido *, pero para IE (y para otros clientes que no admitan rfc 2231) se usaría para la sugerencia del nombre.
autónomo ejemplo:

<?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']; 
} 

*) Eso es un poco como aquí en desbordamiento de pila. El enlace para esta pregunta se muestra como

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

pero también funciona con

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

la parte importante es la identificación 2578349

+0

+1 la mejor respuesta que he visto sobre el tema. Gracias por el enlace. Esto va a mi caja de favoritos. –

+0

Gracias por proporcionarme la explicación detallada realmente ayudó a comprender el problema más profundamente. Gracias – pks83

+0

Hola VolkerK, ¿Alguna información sobre cómo lidiar con Safari? – pks83

0

Creo que si intenta agregar otro juego de caracteres le arreglará su proplem.

si el proplem todavía creo que necesita instalar archivos de idiomas desde el CD de XP a su sistema porque si el sistema no puede encontrar los caracteres correctos, agregará los impares.

Tuve un proyecto como este con idioma árabe pero me parece que no copié todos los archivos de idioma a mi sistema.

Espero que esto te ayude.

Cuestiones relacionadas