web-dev-qa-db-fra.com

Vue / HTML / JS comment télécharger un fichier sur un navigateur en utilisant la balise de téléchargement

Cette question est différente de l'autre réponse fournie, car ma question se concentre sur VUE et si VUE a également un moyen d'empêcher la méthode par défaut.

Cette question est plus spécifique au HTML 5 "téléchargement" avec la liaison VUE du: href et pourquoi cela ne fonctionne pas pour empêcher le comportement par défaut du navigateur d'ouvrir le fichier dans un nouvel onglet.

Comportement attendu: téléchargez le fichier dans le navigateur

Comportement réel: ouvre le fichier dans un nouvel onglet

Exception: seules les images, les fichiers PDF et les navigateurs compatibles sont ouverts dans un nouvel onglet, d'autres fichiers comme .exe sont téléchargés normalement - Pourquoi est-ce que ce comportement peut être changé en html?

L'ajout de target = "_ blank" ne résout pas le problème

<a :href="downloadById(item.url)" download>Download</a>

Lorsque le lien ci-dessus est cliqué, le fichier est ouvert dans un nouvel onglet de navigateur, je dois empêcher ce comportement par défaut et forcer un téléchargement lors du clic. La balise HTML 5 "télécharger" est censée résoudre ce problème ne semble pas fonctionner.

Chrome a récemment déconseillé le formulaire de balise de téléchargement fonctionnant avec les téléchargements interdomaines. vue a-t-il un modificateur pour éviter ce défaut? Y a-t-il d'autres façons de télécharger le fichier en javascript ou en html?

Une solution proposée est de lire l'URL en tant que arrayBuffer puis de créer un nouveau blob dans le DOM, puis de créer un élément d'ancrage et de cliquer dessus. Mais cela semble bizarre de forcer le téléchargement d'un fichier.

Je suis sûr que leur doit être une solution plus propre pour télécharger un fichier sous forme d'URL, c'est un problème trivial, en espérant une solution simple.

Merci.

8
Ricky-U

Un moyen moins hacky d'éviter les problèmes CORS serait d'obtenir le fichier via une demande XHR et de le fournir sous forme de blob:

modèle

<a
  :href="item.url"
  v-text="item.label"
  @click.prevent="downloadItem(item.url)" />

Vue

methods: {
  downloadItem (url) {
    Axios.get(url, { responseType: 'blob' })
      .then(({ data }) => {
        const blob = new Blob([data], { type: 'application/pdf' })
        let link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = 'Download.pdf'
        link.click()
      }).catch(error => console.error(error))
    })
  }
}

J'ai utilisé Axios pour mon exemple, mais vous devriez pouvoir utiliser la bibliothèque de votre choix. Notez également que le type mime du blob et le nom du téléchargement sont câblés pour plus de simplicité.

13
Lars Beck