从浏览器下载JSON对象作为文件

Eug*_* Yu 124 javascript json

我有以下代码让用户下载csv文件中的数据字符串.

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

它工作得很好,如果客户端运行代码它生成空白页并开始下载csv文件中的数据.

所以我尝试用JSON对象做这个

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

但我只看到一个页面上显示了JSON数据,而不是下载它.

我进行了一些研究,这个人声称可以工作,但我认为我的代码没有任何区别.

我在代码中遗漏了什么吗?

感谢您阅读我的问题:)

vol*_*tan 203

这就是我为我的应用程序解决它的方法:

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();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,storageObj是要存储的js对象,"scene.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();
  }
Run Code Online (Sandbox Code Playgroud)

  • 但是,这不会没有限制.您只能下载大约1MB的数据.例如,`var storageObj = []; for(var i = 0; i <1000000; ++ i)storageObj.push('aaa');`在Chrome 61中给出"下载失败 - 网络错误" (12认同)
  • 这是唯一适用于超过~~ 2000个字符数据的解决方案.因为您预先添加了数据: (3认同)
  • @YASHDAVE 使用 `JSON.stringify(exportObj, null, 2)` 代替 (3认同)
  • 它被称为数据URI方案:https://en.wikipedia.org/wiki/Data_URI_scheme (2认同)

Eug*_* Yu 37

找到答案.

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');
Run Code Online (Sandbox Code Playgroud)

似乎对我来说很好.

**所有的归功于@ cowboy-ben-alman,他是上面代码的作者**


小智 24

这将是一个纯粹的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);
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/sz76c083/1

  • 感谢您的回复,即使自从我提出这个问题以来已经过了2年!我更喜欢纯JS而不是jQuery语法. (3认同)

Gau*_*ham 16

您可以尝试使用:

根本不需要处理任何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);
Run Code Online (Sandbox Code Playgroud)

如果你想打印JSON,根据这个答案,你可以使用:

JSON.stringify(data,undefined,2)
Run Code Online (Sandbox Code Playgroud)

  • “根本不需要处理任何 HTML 元素”...并阅读 filesaver.js 的源代码...它正是这样做的,哈哈 (5认同)
  • saveAs() 来自 FileSaver.js - https://github.com/eligrey/FileSaver.js (2认同)
  • 是的。我的意思是,不需要直接处理 HTML 元素。 (2认同)
  • 这是最佳答案,因为它没有1MB的大小限制,并且使用库而不是自定义技巧 (2认同)

mai*_*aia 11

以下对我有用:

/* 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)
}
Run Code Online (Sandbox Code Playgroud)

然后像这样称呼它

saveJSON(myJsonObject, "saved_data.json");
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是一个很好的答案,`initMouseEvent()`是[已弃用](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent)Web标准,不应再使用了.而是使用[`new MouseEvent()`](https://developer.mozilla.org/en/docs/Web/API/MouseEvent)接口.但它只是一个次要的重构. (3认同)

Bra*_*rad 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','application/json');
Run Code Online (Sandbox Code Playgroud)

Edge中的文件名和扩展名存在一个问题,但是在撰写本文时,这似乎是Edge的一个错误,应予以修复。

希望这可以帮助某人


小智 7

    downloadJsonFile(data, filename: string){
        // Creating a blob object from non-blob data using the Blob constructor
        const blob = new Blob([JSON.stringify(data)], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        // Create a new anchor element
        const a = document.createElement('a');
        a.href = url;
        a.download = filename || 'download';
        a.click();
        a.remove();
      }
Run Code Online (Sandbox Code Playgroud)

您可以使用 Blob 轻松自动下载文件并将其传输到第一个参数 downloadJsonFile 中。filename是您要设置的文件的名称。


Abi*_*ido 6

React:将其添加到渲染方法中您想要的位置。

\n\n

\xe2\x80\xa2 对象处于状态

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

props 中的\xe2\x80\xa2 对象:

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

className和style是可选的,根据自己的需要修改style。

\n


zb'*_*zb' 6

如果您更喜欢控制台片段、雷瑟而不是文件名,您可以这样做:

window.open(URL.createObjectURL(
    new Blob([JSON.stringify(JSON)], {
      type: 'application/binary'}
    )
))
Run Code Online (Sandbox Code Playgroud)


MSO*_*ACC 6

2021 年的 ES6+ 版本;也没有 1MB 限制:

这是改编自@maia 的版本,针对现代 Javascript 进行了更新,将已弃用的 initMouseEvent 替换为,new MouseEvent()并且代码总体上得到了改进:

const saveTemplateAsFile = (filename, jsonToWrite) => {
    const blob = new Blob([jsonToWrite], { type: "text/json" });
    const link = document.createElement("a");

    link.download = filename;
    link.href = window.URL.createObjectURL(blob);
    link.dataset.downloadurl = ["text/json", link.download, link.href].join(":");

    const evt = new MouseEvent("click", {
        view: window,
        bubbles: true,
        cancelable: true,
    });

    link.dispatchEvent(evt);
    link.remove()
};
Run Code Online (Sandbox Code Playgroud)

如果你想传入一个对象:

const myObj = {};
const myObjAsJson = JSON.stringify(myObj);

saveTemplateAsFile(myObjAsJson);
Run Code Online (Sandbox Code Playgroud)

  • 我相信你应该在完成后通过调用“link.remove()”来清理“link” (2认同)
  • 我提供离线 html/js 文件的下载,这对我来说比 FileSaver.js 更简单。谢谢你! (2认同)

rob*_*tjd 5

download链接的属性是新的,在 Internet Explorer 中不受支持(请参阅此处的兼容性表)。对于这个问题的跨浏览器解决方案,我会看看FileSaver.js


小智 5

针对仅针对现代浏览器的用户的简单,干净的解决方案:

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');
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

104684 次

最近记录:

6 年,9 月 前