118 votes

Comment définir le nom du fichier téléchargé à partir du navigateur ?

Je suis en train d'écrire une application web qui, entre autres choses, permet aux utilisateurs de télécharger des fichiers sur mon serveur. Afin d'éviter les conflits de noms et d'organiser les fichiers, je les renomme une fois qu'ils sont sur mon serveur. En gardant une trace du nom de fichier d'origine, je peux communiquer avec le propriétaire du fichier sans qu'ils sachent jamais que j'ai changé le nom du fichier en arrière-plan. C'est-à-dire, jusqu'à ce qu'ils aillent télécharger le fichier. Dans ce cas, ils sont invités à télécharger un fichier avec un nom inconnu.

Ma question est la suivante : y a-t-il un moyen de spécifier le nom d'un fichier à télécharger en utilisant uniquement HTML ? Ainsi, un utilisateur télécharge un fichier nommé 'abc.txt' et je le renomme en 'xyz.txt', mais lorsque qu'ils le téléchargent, je voudrais que le navigateur enregistre le fichier sous le nom 'abc.txt' par défaut. Si cela n'est pas possible avec seulement du HTML, y a-t-il un moyen de le faire ?

150voto

Mephiztopheles Points 1121

Lorsqu'ils cliquent sur un bouton pour télécharger le fichier, vous pouvez ajouter l' attribut HTML5 download où vous pouvez définir le nom de fichier par défaut.

C'est ce que j'ai fait, lorsque j'ai créé un fichier xlsx et que le navigateur veut le sauvegarder en tant que fichier zip.

Télécharger
Télécharger l'exportation

Remarquez que l'attribut 'download' ne fonctionne que pour les URLs de même origine.

108voto

Palantir Points 11889

Impossible de trouver un moyen en HTML. Je pense que vous aurez besoin d'un script côté serveur qui enverra un en-tête Content-Disposition. En php, cela se fait comme ceci:

header('Content-Disposition: attachment; filename="downloaded.pdf"');

si vous souhaitez fournir un nom de fichier par défaut, mais pas de téléchargement automatique, cela semble fonctionner.

header('Content-Disposition: inline; filename="filetodownload.jpg"');

En fait, c'est le serveur qui sert directement vos fichiers, vous n'avez donc aucun moyen d'interagir avec lui depuis HTML, car HTML n'est pas du tout impliqué.

7voto

xgqfrms Points 2718

Juste besoin d'utiliser l'attribut télécharger de la balise HTML5 a

codepen démo en direct

https://codepen.io/xgqfrms/full/GyEGzG/

mon raccourci d'écran.

saisissez ici la description de l'image

saisissez ici la description de l'image

mettre à jour la réponse

  1. si un fichier est téléchargeable dépend de la configuration de réponse du serveur, telle que Content-Type, Content-Disposition;

  2. les extensions de fichier à télécharger sont optionnelles, dépendant également de la configuration du serveur.

    'Content-Type': 'application/octet-stream', // cela signifie un fichier binaire inconnu, // les navigateurs ne l'exécutent généralement pas, voire ne demandent pas s'il doit être exécuté.

    'Content-Disposition': attachment; filename=nom_du_serveur.type_de_fichier, // si l'en-tête spécifie un nom de fichier, // il prend le dessus sur un nom de fichier spécifié dans l'attribut de téléchargement.

télécharger le fichier d'url blob

    function generatorBlobVideo(url, type, dom, link) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET', url);
      xhr.responseType = 'arraybuffer';
      xhr.onload = function(res) {
        // console.log('res =', res);
        var blob = new Blob(
          [xhr.response],
          {'type' : type},
        );
        // créer l'url du blob
        var urlBlob = URL.createObjectURL(blob);
        dom.src = urlBlob;
        // télécharger le fichier en utilisant la balise `a`
        link.href = urlBlob;
      };
      xhr.send();
    }

    (function() {
      var type = 'image/png';
      var url = 'https://cdn.xgqfrms.xyz/logo/icon.png';
      var dom = document.querySelector('#img');
      var link = document.querySelector('#img-link');
      generatorBlobVideo(url, type, dom, link);
    })();

https://cdn.xgqfrms.xyz/HTML5/Blob/index.html

références

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#important_mime_types_for_web_developers

4voto

bielb2 Points 11

Même code que @Hillkim Henry mais avec une amélioration a.remove()

Cela force le document à supprimer la balise a du corps et évite les éléments multiples

const coverntFiletoBlobAndDownload = async (file, name) => {
  const blob = await fetch(file).then(r => r.blob())
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  a.download = name // ajouter une extension personnalisée ici
  document.body.appendChild(a)
  a.click()
  window.URL.revokeObjectURL(url)
  // Supprimer la balise "a" du corps
  a.remove()
}

3voto

Hillkim Henry Points 1824

Parfois la réponse de @Mephiztopheles ne fonctionnera pas sur les stockages de blobs et certains navigateurs.

Pour cela, vous devez utiliser une fonction personnalisée pour convertir le fichier en blob et le télécharger

const coverntFiletoBlobAndDownload = async (file, name) => {
  const blob = await fetch(file).then(r => r.blob())
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  a.download = name // ajoutez ici l'extension personnalisée
  document.body.appendChild(a)
  a.click()
  window.URL.revokeObjectURL(url)
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X