我有以下代码,让用户下载数据字符串在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数据,没有下载它。

我进行了一些研究,这一个声称工作,但我没有看到我的代码有任何不同。

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

谢谢你阅读我的问题。


当前回答

React:在你的渲染方法中添加这个。

•状态中的对象:

<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>

•道具中的物体:

<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和style是可选的,根据需要修改样式。

其他回答

找到了答案。

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,他是上面代码的作者**

尝试设置另一种mime类型: exportData = '数据:应用程序/字节流;charset=utf-8,';

但是保存对话框中的文件名可能会有问题。

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

这是从@maia的版本改编而来的,针对现代Javascript进行了更新,将废弃的initMouseEvent替换为新的MouseEvent(),代码总体上得到了改进:

const saveTemplateAsFile = (filename, dataObjToWrite) => {
    const blob = new Blob([JSON.stringify(dataObjToWrite)], { 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()
};

如果你想传递一个对象:

saveTemplateAsFile("filename.json", myDataObj);

对于那些只针对现代浏览器的人来说,简单、干净的解决方案:

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');

我最近不得不创建一个按钮,下载一个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');

在edge中有一个文件名和扩展名的问题,但在撰写本文时,这似乎是edge的一个bug,将被修复。

希望这对大家有所帮助