2011-04-12 13 views
7

¿Cómo enviar un archivo al navegador como archivo adjunto si el archivo significado reside en un servidor de terceros (sin descarga o transmisión previa)?Enviando archivo a un navegador como archivo adjunto

+3

No hay manera de lograr eso. No tiene influencia sobre el manejo de recursos remotos. Y los clientes HTTP no admiten cargas útiles 'mensaje/cuerpo externo'. – mario

Respuesta

-1

Si desea proporcionar archivos que se manejan regularmente por el navegador (imágenes, html, ...), tendrá que añadir una cabecera para cambiar el tipo MIME con algo como:

header("Content-Type: application/force-download; name=filename");

Si usted no tiene acceso al servidor de terceros, que no tienen otra opción para descargar el archivo usted mismo para proporcionar al usuario mediante la adición de la cabecera

+2

Mejor uso * application/octet-stream *. – Gumbo

4

http://php.net/manual/en/function.header.php#example-3655

Si desea que se le solicite al usuario que guarde los datos que está enviando, como un archivo PDF generado, puede utilizar el encabezado »Content-Disposition para proporcionar un nombre de archivo recomendado y forzar al navegador a mostrar el cuadro de diálogo de guardar.

<?php 
// We'll be outputting a PDF 
header('Content-type: application/pdf'); 

// It will be called downloaded.pdf 
header('Content-Disposition: attachment; filename="downloaded.pdf"'); 

// The PDF source is in original.pdf 
readfile('original.pdf'); 
?> 
+0

esto enviaría un archivo almacenado localmente, por favor vuelva a leer la pregunta en cuestión. – RobertPitt

14

De otro servidor sin necesidad de descargar a su servidor:

header('Location: http://thirdparty.com/file.ext'); 

sin necesidad de descargar el archivo localmente usted no tiene ninguna autorización en el servidor externo, lo que tiene que decirle al navegador qué hacer, por lo tanto, el encabezado de redirección, le indicará al servidor que vaya directamente a la url proporcionada, cargando así la descarga.

Desde el servidor, debe hacer:

if (file_exists($file)) 
{ 
    if(false !== ($handler = fopen($file, 'r'))) 
    { 
     header('Content-Description: File Transfer'); 
     header('Content-Type: application/octet-stream'); 
     header('Content-Disposition: attachment; filename='.basename($file)); 
     header('Content-Transfer-Encoding: binary'); 
     header('Expires: 0'); 
     header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
     header('Pragma: public'); 
     header('Content-Length: ' . filesize($file)); //Remove 

     //Send the content in chunks 
     while(false !== ($chunk = fread($handler,4096))) 
     { 
      echo $chunk; 
     } 
    } 
    exit; 
} 
echo "<h1>Content error</h1><p>The file does not exist!</p>"; 

tomado de otra question tengo answered

+6

fopen requiere 2 parámetros, el segundo debe ser el modo, en este caso "r" para leer –

+0

fopen + fread by chunks no es una buena opción, es demasiado lento. Use readfile ($ file) después de los encabezados para acelerar. – Asaelko

0

Como los otros han dicho, hay que establecer la cabecera Content-disposition de la respuesta al archivo solicitud de descarga Sin embargo, has dicho que el archivo está en un servidor de terceros. A menos que tenga control sobre cómo el servidor envía el archivo, no puede cambiar la forma en que el navegador recupera de ese servidor.

Sin embargo, puede realizar un proxy del archivo para que su servidor descargue el archivo y luego lo pase al cliente con los encabezados correspondientes. Esto significa que ha duplicado su factura de ancho de banda, ya que tiene que descargar el archivo Y subirlo al mismo tiempo.

+0

lo dijo sin descarga o transmisión previa. – RobertPitt

+0

@RobertPitt: ¿Magia, entonces? – drudge

+0

No del todo, el uso de la función de redirección creará la * ilusión * de que el archivo se está descargando de su servidor. – RobertPitt

0

Solo una nota para aquellos que enfrentan problemas con los nombres que contienen espacios (por ejemplo, "test test.pdf").

En los ejemplos (99% del tiempo) puede encontrar el encabezado ('Content-Disposition: attachment; filename ='. Basename ($ file));

pero la forma correcta de establecer el nombre de archivo es citando (comillas dobles): header ('Content-Disposition: attachment; filename = "'. Basename ($ file). '"');

Algunos navegadores pueden trabajar sin cita, pero seguro que no es Firefox y como explica Mozilla, la cotización del nombre de archivo en el contenido-disposición está de acuerdo con el RFC http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

Cuestiones relacionadas