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

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

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

谢谢你阅读我的问题。


当前回答

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

其他回答

我最近不得不创建一个按钮,下载一个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,将被修复。

希望这对大家有所帮助

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

这是我如何解决我的应用程序:

。.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对象,而“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();
  }
    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();
      }

你可以使用Blob轻松地自动下载文件,并在第一个参数downloadJsonFile中传输它。Filename是要设置的文件名。

你可以尝试使用:

原生JavaScript API的Blob构造函数和 FileSaver.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'
});

// Save the file
saveAs(fileToSave, fileName);

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

JSON.stringify(data,undefined,2)