Загрузите объект JSON в виде файла из браузера
у меня есть следующий код, чтобы пользователи могли загружать строки данных в csv-файл.
exportData = 'data:text/csv;charset=utf-8,';
exportData += 'some csv strings';
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);
он работает просто отлично, что если клиент запускает код, он генерирует пустую страницу и начинает загрузку данных в csv-файл.
поэтому я попытался сделать это с помощью объекта JSON, например
exportData = 'data:text/json;charset=utf-8,';
exportData += escape(JSON.stringify(jsonObject));
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);
но я вижу только страницу с данными JSON, отображаемыми на ней, не загружая ее.
Я прошла некоторые исследования, и это один утверждает, что работает, но я не вижу разница в моем коде.
Я что-то упустил в своем коде?
Спасибо, что прочитали мой вопрос:)
10 ответов:
вот как я решил его для моего приложения:
HTML:
<a id="downloadAnchorElem" style="display:none"></a>
JS (чистый JS, а не jQuery здесь):
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();
в этом случае
storageObj
это объект js, который вы хотите сохранить, и " сцена.json " - это просто примерное имя для результирующего файла.этот подход имеет следующие преимущества перед другими предложенными:
- ни один HTML-элемент не должен быть нажат
- результат будет назван так, как вы хотите это
- jQuery не требуется
мне нужно было это поведение без явного нажатия, так как я хочу, чтобы вызвать загрузку автоматически в какой-то момент из js.
JS решение (не требуется 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(); }
нашел ответа.
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');
Кажется, работает хорошо для меня.
* * вся заслуга принадлежит @cowboy-ben-alman, который является автором кода выше **
Это будет чистая версия JS (адаптированная из cowboy's):
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);
для меня сработало следующее:
/* 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) }
а потом называть это так
saveJSON(myJsonObject, "saved_data.json");
вы можете попробовать использовать:
- собственный Javascript API Blob строитель
- the Сохранитель файлов.js
saveAs()
методнет необходимости иметь дело с любыми элементами HTML вообще.
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);
Если вы хотели довольно распечатать JSON, за ответ, вы могли бы использовать:
JSON.stringify(data,undefined,2)
на
download
свойство ссылок является новым и не поддерживается в Internet Explorer (см. таблицу совместимости здесь). Для кросс-браузерного решения этой проблемы я бы посмотрел на Сохранитель файлов.js
простое, чистое решение для тех, кто ориентирован только на современные браузеры:
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');
попробуйте установить другой тип MIME:
exportData = 'data:application/octet-stream;charset=utf-8,';
но там могут быть проблемы с именем файла в диалоге сохранения.
недавно мне пришлось создать кнопку, которая будет загружать JSON-файл всех значений большой формы. Мне это нужно было для работы с IE/Edge / Chrome. Вот что я сделал:
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');
была одна проблема с именем файла и расширением в edge, но на момент написания это казалось ошибкой с Edge, которая должна быть исправлена.
надеюсь, это поможет кому-то
реагировать добавить это, где вы хотите в вашем методе render.
• объект в состояние:
<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>
• объект в реквизит:
<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>
имя класса и стиль являются необязательными, измените стиль в соответствии с вашими потребностями.