2011-05-14 33 views
15

He estado desarrollando una nueva aplicación web que se basa en Amazon S3 servidores como sistema de almacenamiento, y Codeiginter como el marco PHP.Forzar la descarga de servidores s3 amazon

Necesito forzar el archivo para descargar cuando se hace clic en el enlace. La dirección URL original es el siguiente:

http://www.our-web.com/download/do/1.jpg

que genera una URL temporal firmado con el archivo existente en los servidores de Amazon S3 como esto:

http://main_bucket.s3.amazonaws.com/post/1/1.jpg?AWSAccessKeyId=AKIAJEOQKYPKC3CCU5RA&Expires=1305395426&Signature=iuzCdA22gImLK192%2BMAhk8OkAY8%3D

Necesito hacer el inicio del archivo descargando de la URL real de Amazon tan pronto como el usuario haga clic en el enlace.

tengo ahora dos maneras de hacerlo:

  1. Use redirect() que se abrirá el archivo no se descarga; o
  2. cabeceras como Alter este código:

    header('Content-type: application/force-download'); 
    header('Content-Disposition: attachment; filename=' . $file_name); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 4000'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . filesize($generated_file)); 
    
    readfile($generated_file); 
    

Por desgracia, las dos cosas no me ayudan. El segundo método hace que la descarga provenga de mi sitio web y no directamente de Amazon.

¿Cómo puedo forzar la descarga del archivo directamente desde los servidores de Amazon S3, y no desde mi sitio web?

+0

file_get_contents uso o un rizo retrive el archivo S3 luego hacer una pasarela con las cabeceras –

+0

Eso es lo que había de hacer con ' readfile'. – Lasar

+0

correcto, pero a pesar de que no quiero que el cliente descargue el archivo a través de mi sitio web. debe haber una mejor solución para descargar desde otro dominio. – Khaled

Respuesta

24

Solo tiene que establecer los encabezados correctos en sus archivos en S3 para forzar al navegador a descargar en lugar de abrir el archivo. Establezca estos:

Content-Disposition: attachment; filename=FILENAME.EXT 
Content-Type: application/octet-stream 

Deberá configurarlos al cargar los archivos en S3. Con el php SDK usaría create_object.

O puede configurar estos después de cargar usando 'change_content_type' o por copying the file to itself en S3 y estableciendo los encabezados correctos.

+0

si esto es todo, eso funcionó muy bien para mí, muchas gracias – Khaled

+1

se ha resuelto cambiando el archivo meta como este código dice: \t \t $ opt ['meta'] ['Content-Type'] = 'binary/octet-stream'; – Khaled

+0

@Khaled - Genial. Me alegro de ayudar :) –

-1

No puede decirle al navegador cómo manejar un archivo remoto. Al redirigir a Amazon le está diciendo al navegador que inicie una nueva solicitud allí. Usted no tiene ningún control sobre esa solicitud.

La única solución que se me ocurre es empacar la imagen en un archivo zip o similar. Por supuesto, eso agrega otra forma de complejidad (probablemente molesta).

+0

la imagen es solo un ejemplo, tal vez me olvide mencionar que se permiten varios tipos de archivos especialmente pdf y docx. De todos modos, gracias por la respuesta, pero creo que hay una manera de resolver esto. En realidad, muchos sitios web grandes usan un sistema de almacenamiento externo. – Khaled

+0

No estaba al tanto de la posibilidad de establecer encabezados al cargar un archivo a S3. Es bueno saberlo. – Lasar

+0

es posible, creo que Amazon aún tiene mejores soluciones para ofrecer, razón por la cual elegimos amazon s3 porque tiene carga directa usando POST directamente desde el navegador. gracias por la ayuda de todos modos – Khaled

8

La pregunta es acerca de la configuración mediante programación, pero para hacerlo de forma manual a través de la consola de AWS:

~ Select a file in S3. 
~ Properties > Metadata > Add more metadata 
~ Key: Content-Disposition Value: Attachment 
~ Save 
+0

Muy útil ya que esta respuesta tiene un alto puntaje en las búsquedas de Google, y necesitaba mostrarle a una persona no tecnológica cómo hacer esto en AWS. – Nick

6

poco tarde a la fiesta, pero muchas veces con un archivo que no quieren tener que decidir en el momento del almacenamiento, cómo se usará. Desea poder almacenar el archivo una vez, luego en un área posiblemente incrustar el archivo o mostrarlo en el navegador, y en otra área habilitar al usuario para descargar el mismo archivo.

Afortunadamente, puede hacerlo proporcionando parámetros de anulación en la url de solicitud.Solo funciona con solicitudes firmadas, pero afortunadamente ya lo estás haciendo.

Si agrega un parámetro como &request-content-type="application/force-download" que debería hacer el truco.

Mira la parámetros de la petición sección de la documentación objeto Get S3: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html

+4

Creo que el parámetro de solicitud correcto es 'request-content-disposition = attachment; filename = FILENAME.EXT "' Tu 'request-content-type' está funcionando porque es un tipo de contenido desconocido para que el navegador lo descargue de manera predeterminada. – Seth

+0

Brillante, sí, esto es lo que buscaba. Preferiría no decidir esto en el almacenamiento tiempo (sobre todo porque ya hay miles de archivos en S3 que no quiero modificar). –