2011-05-14 2 views
15

J'ai développé une nouvelle application web qui repose sur les serveurs Amazon S3 comme système de stockage, et Codeiginter comme framework PHP.Forçage Téléchargement à partir de serveurs s3 amazon

Je dois forcer le téléchargement du fichier lorsque l'utilisateur clique sur le lien. L'URL originale ressemble à ceci:

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

qui génère une URL temporaire signé au fichier réel sur les serveurs Amazon S3 comme ceci:

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

que je dois faire le début de fichier le téléchargement de l'URL Amazon réel dès que l'utilisateur clique sur le lien.

J'ai deux façons de le faire maintenant:

  1. Utilisez redirect() qui ouvrira le fichier ne le télécharger; ou
  2. têtes Alter comme ce code:

    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); 
    

Malheureusement, les deux moyens ne me permettent pas. La deuxième méthode provoque le téléchargement à venir de mon site Web et non directement à partir d'Amazon.

Comment puis-je forcer le téléchargement direct du fichier à partir des serveurs Amazon S3, et non de mon site Web?

+0

file_get_contents utilisation ou cURL retrive le fichier S3 puis faire un passthrough avec les en-têtes –

+0

C'est ce qu'il avait fait avec ' readfile'. – Lasar

+0

correct, mais même si je ne veux pas que le client télécharge le fichier via mon site Web. il doit y avoir une meilleure solution pour télécharger depuis un autre domaine. – Khaled

Répondre

24

Vous avez juste besoin de définir les en-têtes corrects sur vos fichiers dans S3 afin de forcer le navigateur à télécharger plutôt que d'ouvrir le fichier. Définissez ces paramètres:

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

Vous devrez les définir lors du téléchargement des fichiers vers S3. Avec le php SDK vous utiliseriez create_object.

Vous pouvez également les définir après le téléchargement en utilisant 'change_content_type' ou copying the file to itself en S3 et en définissant les en-têtes appropriés.

+0

oui c'est ça, ça a bien fonctionné pour moi, merci beaucoup – Khaled

+1

ça a été résolu en changeant la méta de fichier comme le dit ce code: \t \t $ opt ['meta'] ['Content-Type'] = 'binary/octet-stream'; – Khaled

+0

@Khaled - Super. Heureux d'aider :) –

-1

Vous ne pouvez pas dire au navigateur comment gérer un fichier distant. En redirigeant vers Amazon, vous demandez au navigateur de lancer une nouvelle requête là-bas. Vous n'avez aucun contrôle sur cette requête.

La seule solution à laquelle je puisse penser est de conditionner l'image dans un fichier zip ou similaire. Bien sûr, cela ajoute une autre forme de complexité (probablement ennuyante).

+0

l'image est juste un exemple, peut-être que j'oublie de mentionner que plusieurs types de fichiers est autorisé spécialement pdf, et docx. Quoi qu'il en soit, merci pour la réponse, mais je pense qu'il y a un moyen de comprendre cela. En fait beaucoup de grands sites utilise un système de stockage externe. – Khaled

+0

Je n'étais pas au courant de la possibilité de définir des en-têtes lors du téléchargement d'un fichier vers S3. C'est bon à savoir. – Lasar

+0

il est possible, je pense que amazon a encore de meilleures solutions à fournir, la raison pour laquelle nous avons choisi amazon s3 parce qu'il a directement télécharger en utilisant POST directement à partir du navigateur. merci pour l'aide de toute façon – Khaled

8

La question est sur la définition de ce programme, mais de le faire manuellement via la console AWS:

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

Très utile puisque cette réponse se classe très bien dans google recherches, et je devais montrer à une personne non-tech comment le faire sur AWS. – Nick

6

peu tard à la fête, mais souvent avec un fichier que vous ne voulez pas avoir à décider au moment du stockage comment il sera utilisé. Vous voulez être en mesure de stocker le fichier une fois, puis dans une zone peut-être intégrer le fichier ou l'affichage dans le navigateur, et dans une autre zone permettent à l'utilisateur de télécharger le même fichier. Heureusement, vous pouvez le faire en fournissant des paramètres de remplacement dans l'URL de la requête.Cela fonctionne uniquement avec les demandes signées, mais heureusement, vous le faites déjà.

Si vous ajoutez un paramètre comme &request-content-type="application/force-download" qui devrait faire l'affaire.

Vérifiez les requête Paramètres section de la S3 GET Documentation objet: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html

+4

Je crois que le paramètre de requête correct est 'request-content-disposition = attachment; filename = FILENAME.EXT "'. Votre 'request-content-type' fonctionne parce que c'est un type de contenu inconnu donc le navigateur le télécharge par défaut – Seth

+0

Brillant, oui c'est ce que je recherchais. temps (d'autant plus qu'il y a déjà des milliers de fichiers en S3 que je ne veux pas modifier). –