web-dev-qa-db-fra.com

Nom de fichier blob JavaScript sans lien

Comment définir le nom d'un fichier blob en JavaScript lorsque vous le forcez à le télécharger via window.location?

function newFile(data) {
    var json = JSON.stringify(data);
    var blob = new Blob([json], {type: "octet/stream"});
    var url  = window.URL.createObjectURL(blob);
    window.location.assign(url);
}

L'exécution du code ci-dessus télécharge instantanément un fichier sans actualisation de page ressemblant à ceci:

bfefe410-8d9c-4883-86c5-d76c50a24a1d

Je veux définir le nom de fichier comme my-download.json .

150
Ash Blue

Le seul moyen que je connaisse est le truc utilisé par FileSaver.js :

  1. Créez une balise <a> cachée.
  2. Définissez son attribut href sur l'URL du blob.
  3. Définissez son attribut download sur le nom du fichier.
  4. Cliquez sur la balise <a>.

Voici un exemple simplifié ( jsfiddle ):

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);

J'ai écrit cet exemple juste pour illustrer l'idée. Dans le code de production, utilisez plutôt FileSaver.js.

Notes

  • Les anciens navigateurs ne supportent pas l'attribut "download", car il fait partie de HTML5.
  • Certains formats de fichiers sont considérés comme non sécurisés par le navigateur et le téléchargement échoue. L'enregistrement de fichiers JSON avec extension txt fonctionne pour moi.
265
kol

Je voulais juste développer la réponse acceptée en prenant en charge Internet Explorer (les versions les plus modernes, en tout cas), et ranger le code à l'aide de jQuery:

$(document).ready(function() {
    saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});

function saveFile (name, type, data) {
    if (data !== null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

Voici un exemple de violon . Godspeed .

40
Alexandru

Même principe que les solutions ci-dessus. Mais j'avais des problèmes avec Firefox 52.0 (32 bits) où des fichiers volumineux (> 40 Mo) étaient tronqués à des positions aléatoires. La reprogrammation de l'appel de revokeObjectUrl () corrige ce problème.

function saveFile(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    }, 0)
  }
}
18
Kim Nyholm

En retard, mais depuis que j'ai le même problème, j'ajoute ma solution:

function newFile(data, fileName) {
    var json = JSON.stringify(data);
    //IE11 support
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        let blob = new Blob([json], {type: "application/json"});
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {// other browsers
        let file = new File([json], fileName, {type: "application/json"});
        let exportUrl = URL.createObjectURL(file);
        window.location.assign(exportUrl);
        URL.revokeObjectURL(exportUrl);
    }
}
11
ben
saveFileOnUserDevice = function(file){ // content: blob, name: string
        if(navigator.msSaveBlob){ // For ie and Edge
            return navigator.msSaveBlob(file.content, file.name);
        }
        else{
            let link = document.createElement('a');
            link.href = window.URL.createObjectURL(file.content);
            link.download = file.name;
            document.body.appendChild(link);
            link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
            link.remove();
            window.URL.revokeObjectURL(link.href);
        }
    }
6
Jean-Philippe