从浏览器下载 JSON 对象作为文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19721439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Download JSON object as a file from browser
提问by Eugene Yu
I have the following code to let users download data strings in csv file.
我有以下代码让用户下载 csv 文件中的数据字符串。
exportData = 'data:text/csv;charset=utf-8,';
exportData += 'some csv strings';
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);
It works just fine that if client runs the code it generates blank page and starts downloading the data in csv file.
它工作得很好,如果客户端运行代码,它会生成空白页面并开始下载 csv 文件中的数据。
So I tried to do this with JSON object like
所以我试图用 JSON 对象来做到这一点
exportData = 'data:text/json;charset=utf-8,';
exportData += escape(JSON.stringify(jsonObject));
encodedUri = encodeURI(exportData);
newWindow = window.open(encodedUri);
But I see only a page with the JSON data displayed on it, not downloading it.
但我只看到一个页面,上面显示了 JSON 数据,而不是下载它。
I went through some research and this oneclaims to work but I don't see any difference to my code.
我进行了一些研究,这个研究声称可以工作,但我看不出我的代码有什么不同。
Am I missing something in my code?
我的代码中遗漏了什么吗?
Thanks for reading my question:)
感谢您阅读我的问题:)
回答by volzotan
This is how I solved it for my application:
这就是我为我的应用程序解决它的方法:
HTML:
<a id="downloadAnchorElem" style="display:none"></a>
HTML:
<a id="downloadAnchorElem" style="display:none"></a>
JS (pure JS, not jQuery here):
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();
In this case, storageObjis the js object you want to store, and "scene.json" is just an example name for the resulting file.
在这种情况下,storageObj是您要存储的 js 对象,而“scene.json”只是结果文件的示例名称。
This approach has the following advantages over other proposed ones:
与其他提议的方法相比,这种方法具有以下优点:
- No HTML element needs to be clicked
- Result will be named as you want it
- no jQuery needed
- 无需点击 HTML 元素
- 结果将根据您的需要命名
- 不需要jQuery
I needed this behavior without explicit clicking since I want to trigger the download automatically at some point from js.
我不需要显式点击就需要这种行为,因为我想在某个时候从 js 自动触发下载。
JS solution (no HTML required):
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();
}
回答by Eugene Yu
Found an answer.
找到了答案。
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');
seems to work fine for me.
似乎对我来说很好。
** All credit goes to @cowboy-ben-alman, who is the author of the code above **
** 所有功劳归于@cowboy-ben-alman,他是上述代码的作者 **
回答by jbcdefg
This would be a pure JS version (adapted from cowboy's):
这将是一个纯 JS 版本(改编自牛仔的):
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);
回答by Gautham
You could try using:
您可以尝试使用:
- the native JavaScript API's Blobconstructor and
- the FileSaver.js
saveAs()method
- 原生 JavaScript API 的Blob构造函数和
- 该FileSaver.js
saveAs()方法
No need to deal with any HTML elements at all.
根本不需要处理任何 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);
If you wanted to pretty print the JSON, per this answer, you could use:
如果你想漂亮地打印 JSON,根据这个答案,你可以使用:
JSON.stringify(data,undefined,2)
回答by maia
The following worked for me:
以下对我有用:
/* 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)
}
and then to call it like so
然后像这样称呼它
saveJSON(myJsonObject, "saved_data.json");
回答by Brad
I recently had to create a button that would download a json file of all values of a large form. I needed this to work with IE/Edge/Chrome. This is what I did:
我最近不得不创建一个按钮来下载一个包含大型表单所有值的 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','application/json');
There was one issue with filename and extension in edge but at the time of writing this seemed to be a bug with Edge that is due to be fixed.
Edge 中的文件名和扩展名存在一个问题,但在撰写本文时,这似乎是 Edge 的一个错误,需要修复。
Hope this helps someone
希望这有助于某人
回答by Brad
Simple, clean solution for those who only target modern browsers:
适用于仅针对现代浏览器的用户的简单、干净的解决方案:
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');
回答by robertjd
The downloadproperty of links is new and not is supported in Internet Explorer (see the compatibility table here). For a cross-browser solution to this problem I would take a look at FileSaver.js
download链接的属性是新的,在 Internet Explorer 中不受支持(请参阅此处的兼容性表)。对于这个问题的跨浏览器解决方案,我会看看FileSaver.js
回答by Abido
React: add this where you want in your render method.
React:在你的渲染方法中你想要的地方添加这个。
? Object in state:
? 对象状态:
<a
className="pull-right btn btn-primary"
style={{ margin: 10 }}
href={`data:text/json;charset=utf-8,${encodeURIComponent(
JSON.stringify(this.state.objectToDownload)
)}`}
download="data.json"
>
DOWNLOAD DATA AS JSON
</a>
? Object in 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 and style are optional, modify the style according to your needs.
className 和 style 是可选的,根据您的需要修改样式。
回答by minimulin
Try to set another MIME-type:
exportData = 'data:application/octet-stream;charset=utf-8,';
尝试设置另一个 MIME 类型:
exportData = 'data:application/octet-stream;charset=utf-8,';
But there are can be problems with file name in save dialog.
但是保存对话框中的文件名可能存在问题。

