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:)
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();
}
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 * *
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);
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");
vous pouvez essayer d'utiliser:
- le natif de l'API JavaScript Blob constructeur et
- le FileSaver.js
saveAs()
méthode
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)
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
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');
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.
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
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.