Télécharger l'objet JSON en tant que fichier à partir du navigateur

j'ai le code suivant pour permettre aux utilisateurs de télécharger des chaînes de données dans le fichier csv.

exportData = 'data:text/csv;charset=utf-8,';
exportData += 'some csv strings';
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);

cela fonctionne très bien que si le client exécute le code il génère la page blanche et commence à télécharger les données dans le fichier csv.

alors j'ai essayé de le faire avec un objet JSON comme

exportData = 'data:text/json;charset=utf-8,';
exportData += escape(JSON.stringify(jsonObject));
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);

mais je ne vois qu'une page avec les données JSON affichées dessus, et non téléchargées.

j'ai fait quelques recherches et celui-ci prétend travailler mais je ne vois aucune différence avec mon code.

est-ce que je manque quelque chose dans mon code?

Merci d'avoir lu ma question:)

86
demandé sur Community 2013-11-01 09:42:15

10 réponses

Voici comment je l'ai résolu pour mon application:

HTML: <a id="downloadAnchorElem" style="display:none"></a>

JS (pur JS, pas jQuery ici):

var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(storageObj));
var dlAnchorElem = document.getElementById('downloadAnchorElem');
dlAnchorElem.setAttribute("href",     dataStr     );
dlAnchorElem.setAttribute("download", "scene.json");
dlAnchorElem.click();

dans ce cas, storageObj est l'objet js que vous voulez stocker, et" scène.json " est juste un nom d'exemple pour le fichier résultant.

cette approche présente les avantages suivants par rapport aux autres propositions:

  • Aucun élément HTML besoins pour être cliqué sur
  • Résultat sera nommé comme vous le voulez
  • pas de jQuery nécessaire

j'avais besoin de ce comportement sans clic explicite car je veux déclencher le téléchargement automatiquement à un moment donné à partir de js.

JS solution (pas de HTML):

  function downloadObjectAsJson(exportObj, exportName){
    var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj));
    var downloadAnchorNode = document.createElement('a');
    downloadAnchorNode.setAttribute("href",     dataStr);
    downloadAnchorNode.setAttribute("download", exportName + ".json");
    document.body.appendChild(downloadAnchorNode); // required for firefox
    downloadAnchorNode.click();
    downloadAnchorNode.remove();
  }
124
répondu volzotan 2018-05-28 08:12:08

a trouvé une réponse.

var obj = {a: 123, b: "4 5 6"};
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj));

$('<a href="data:' + data + '" download="data.json">download JSON</a>').appendTo('#container');

semble fonctionner pour moi.

* * tout le mérite revient à @cowboy-ben-alman, qui est l'auteur du code ci-dessus * *

32
répondu Eugene Yu 2015-01-06 11:32:04

Ce serait un pur JS version (adapté à partir de cow-boy):

var obj = {a: 123, b: "4 5 6"};
var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj));

var a = document.createElement('a');
a.href = 'data:' + data;
a.download = 'data.json';
a.innerHTML = 'download JSON';

var container = document.getElementById('container');
container.appendChild(a);

http://jsfiddle.net/sz76c083/1

22
répondu jbcdefg 2015-06-09 09:09:24

ce qui suit a fonctionné pour moi:

/* function to save JSON to file from browser
* adapted from http://bgrins.github.io/devtools-snippets/#console-save
* @param {Object} data -- json object to save
* @param {String} file -- file name to save to 
*/
function saveJSON(data, filename){

    if(!data) {
        console.error('No data')
        return;
    }

    if(!filename) filename = 'console.json'

    if(typeof data === "object"){
        data = JSON.stringify(data, undefined, 4)
    }

    var blob = new Blob([data], {type: 'text/json'}),
        e    = document.createEvent('MouseEvents'),
        a    = document.createElement('a')

    a.download = filename
    a.href = window.URL.createObjectURL(blob)
    a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
    e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
    a.dispatchEvent(e)
}

et puis de l'appeler ainsi

saveJSON(myJsonObject, "saved_data.json");
7
répondu maia 2017-01-09 17:23:27

vous pouvez essayer d'utiliser:

aucun élément HTML à traiter.

var data = {
    key: 'value'
};
var fileName = 'myData.json';

// Create a blob of the data
var fileToSave = new Blob([JSON.stringify(data)], {
    type: 'application/json',
    name: fileName
});

// Save the file
saveAs(fileToSave, fileName);

si vous voulez joliment imprimer le JSON, par cette réponse , vous pouvez utiliser:

JSON.stringify(data,undefined,2)
5
répondu Gautham 2018-09-14 10:47:37

la propriété download de links est nouvelle et n'est pas prise en charge dans Internet Explorer (voir la table de compatibilité ici ). Pour une solution Cross-browser à ce problème, je jetterais un oeil à FileSaver.js

4
répondu robertjd 2014-08-23 00:15:05

solution simple et propre pour ceux qui ne ciblent que les navigateurs modernes:

function downloadTextFile(text, name) {
  const a = document.createElement('a');
  const type = name.split(".").pop();
  a.href = URL.createObjectURL( new Blob([text], { type:`text/${type === "txt" ? "plain" : type}` }) );
  a.download = name;
  a.click();
}

downloadTextFile(JSON.stringify(myObj), 'myObj.json');
2
répondu Joe 2018-08-12 13:18:42

essayez de définir un autre type MIME: exportData = 'data:application/octet-stream;charset=utf-8,';

mais il peut y avoir des problèmes avec le nom de fichier dans la boîte de dialogue Enregistrer.

1
répondu mr.Stiher 2013-11-01 06:47:34

j'ai récemment dû créer un bouton qui téléchargerait un fichier json de toutes les valeurs d'une grande forme. J'en avais besoin pour travailler avec IE/Edge/Chrome. C'est ce que j'ai fait:

function download(text, name, type)
    {
        var file = new Blob([text], {type: type});
        var isIE = /*@cc_on!@*/false || !!document.documentMode;
        if (isIE)
        {
            window.navigator.msSaveOrOpenBlob(file, name);
        }
        else
        {
            var a = document.createElement('a');
            a.href = URL.createObjectURL(file);
            a.download = name;
            a.click();
        }
     }

download(jsonData, 'Form_Data_.json','text/json');

il y avait un problème avec le nom du fichier et l'extension dans edge mais au moment de l'écriture cela semblait être un bug avec Edge qui doit être corrigé.

Espérons que cela aide quelqu'un

1
répondu Brad 2017-04-13 09:19:05

React : ajoutez ceci où vous voulez dans votre méthode de rendu.

"151920920 • * objet dans l'état :

<a
  className="pull-right btn btn-primary"
  style={{ margin: 10 }}
  href={`data:text/json;charset=utf-8,${encodeURIComponent(
  JSON.stringify(this.props.objectToDownload)
  )}`}
  download="data.json"
>
  DOWNLOAD DATA AS JSON
</a>

• objet dans props :

<a
  className="pull-right btn btn-primary"
  style={{ margin: 10 }}
  href={`data:text/json;charset=utf-8,${encodeURIComponent(
  JSON.stringify(this.props.objectToDownload)
  )}`}
  download="data.json"
>
  DOWNLOAD DATA AS JSON
</a>

className et style sont optionnels, modifiez le style en fonction de vos besoins.

0
répondu Abido 2018-10-02 14:53:50