Ai-je besoin de Content-Type: application / octet-stream pour télécharger un fichier?

414

La norme HTTP dit:

Si cet en-tête [Content-Disposition: attachment] est utilisé dans une réponse avec le type de contenu application / octet-stream, la suggestion implicite est que l'agent utilisateur ne doit pas afficher la réponse, mais saisit directement une `sauvegarde de la réponse sous .. . 'dialogue.

Je lis cela comme

Content-Type: application/octet-stream
Content-Disposition: attachment

Mais j'aurais pensé que Content-Typeserait application/pdf, image/pngetc.

Dois-je l'avoir Content-Type: application/octet-streamsi je souhaite que les navigateurs téléchargent le fichier?

Paul Draper
la source

Réponses:

959

Non.

Le type de contenu doit être celui qu'il est connu, si vous le savez. application/octet-streamest défini comme "données binaires arbitraires" dans la RFC 2046, et il y a ici un chevauchement certain qui est approprié pour les entités dont le seul but est d'être enregistré sur le disque, et à partir de ce moment, en dehors de tout ce qui est "Webby". Ou de le regarder d'une autre direction; la seule chose que l'on peut faire en toute sécurité avec application / octet-stream est de l'enregistrer dans un fichier et d'espérer que quelqu'un d'autre sait à quoi il sert.

Vous pouvez combiner l'utilisation de Content-Dispositionavec d'autres types de contenu, comme image/pngou même text/htmlpour indiquer que vous souhaitez enregistrer plutôt que d'afficher. Auparavant, certains navigateurs l'ignoraient dans le cas de text/htmlmais je pense que c'était il y a longtemps à ce stade (et je vais bientôt me coucher donc je ne vais pas commencer à tester tout un tas de navigateurs en ce moment, peut-être plus tard).

La RFC 2616 mentionne également la possibilité de jetons d'extension, et de nos jours la plupart des navigateurs reconnaissent inlineque vous voulez que l'entité soit affichée si possible (c'est-à-dire, si c'est un type que le navigateur sait afficher, sinon il n'a pas le choix en la matière) . C'est bien sûr le comportement par défaut de toute façon, mais cela signifie que vous pouvez inclure la filenamepartie de l'en-tête, que les navigateurs utiliseront (peut-être avec quelques ajustements pour que les extensions de fichier correspondent aux normes du système local pour le type de contenu en question, peut-être pas) comme suggestion si l'utilisateur essaie d'enregistrer.

Par conséquent:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"

Signifie "Je ne sais pas de quoi il s'agit. Veuillez l'enregistrer en tant que fichier, de préférence nommé picture.png".

Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"

Signifie "Ceci est une image PNG. Veuillez l'enregistrer en tant que fichier, de préférence nommé picture.png".

Content-Type: image/png
Content-Disposition: inline; filename="picture.png"

Signifie "Ceci est une image PNG. Veuillez l'afficher à moins que vous ne sachiez pas comment afficher les images PNG. Sinon, ou si l'utilisateur choisit de l'enregistrer, nous recommandons le nom picture.png pour le fichier sous lequel vous l'enregistrez".

Parmi les navigateurs qui reconnaissent que inlinecertains l’utiliseraient toujours, tandis que d’autres l’utiliseraient si l’utilisateur avait sélectionné «enregistrer le lien sous» mais pas s’ils avaient sélectionné «enregistrer» lors de la visualisation (ou du moins IE était comme ça, il peut avoir changé il y a quelques années).

Jon Hanna
la source
30
Ce fut une excellente réponse, et ce serait vraiment bien si les choses fonctionnaient comme ça. Mais malheureusement, tous les navigateurs sont pour la plupart en panne. Par exemple, Google Chrome n'ouvrira pas de fenêtre "d'enregistrement de fichier" pour vous s'il s'agit de votre réponse à partir d'un formulaire, indépendamment de l'inclusion de "Content-Disposition: attachment", même avec "application / octet-stream" comme type de contenu . Et puis ils impriment un message disant que vous pourriez être attaqué ... Il n'y a tout simplement aucun moyen de me permettre d'enregistrer un fichier. Vous devez configurer xdg-open même si vous souhaitez simplement enregistrer un fichier. J'en ai marre de ceci.
dividebyzero
1
@dividebyzero n'est pas un problème que j'ai jamais eu, y compris avec Chrome. Y a-t-il autre chose d'inhabituel dans ce que vous faites?
Jon Hanna
1
Le téléchargement d'un fichier avec le enctype par défaut serait incorrect et peut-être que le résultat de cela a déclenché une détection d'attaque, plutôt que de simplement tomber pour rendre le contenu du fichier disponible.
Jon Hanna
7
@Wilt si le client veut sauver, alors il n'a pas d' importance ce que les en- têtes sont envoyés (vous pouvez « Enregistrer » ou « Enregistrer le lien sous » sur quoi que ce soit dans votre navigateur), comme les en- têtes sont des informations, pas de règles si attachmentpourrait être considéré comme «préférable de ne pas afficher cela vous-même» alors inlineque «préférable de l'afficher vous-même si vous le pouvez». Dans les deux cas, la plupart des navigateurs utiliseront la valeur du nom de fichier comme nom suggéré du fichier, mais les utilisateurs peuvent toujours le remplacer.
Jon Hanna
1
@Tresdin merci. Je suis un peu perplexe que ce soit si populaire, par rapport à certains de mes autres que je considérerais mieux, mais je suppose que cela a dû arriver à répondre aux problèmes des gens.
Jon Hanna