我最近一直在摆弄WebGL,并得到了一个Collada阅读器工作。问题是它非常慢(Collada是一种非常冗长的格式),所以我将开始将文件转换为更容易使用的格式(可能是JSON)。我已经有代码来解析JavaScript文件,所以我不妨使用它作为我的出口商太!问题在于储蓄。

现在,我知道我可以解析文件,将结果发送到服务器,并让浏览器从服务器请求返回文件作为下载。但实际上,服务器与这个特定的进程没有任何关系,那么为什么要把它牵扯进来呢?我在内存中已经有了所需文件的内容。是否有任何方法可以使用纯JavaScript向用户提供下载?(我对此表示怀疑,但不妨问问……)

需要明确的是:我不会在用户不知情的情况下访问文件系统!用户将提供一个文件(可能通过拖放),脚本将转换内存中的文件,并提示用户下载结果。就浏览器而言,所有这些都应该是“安全”的活动。

[编辑]:我没有在前面提到它,所以那些回答“Flash”的帖子是有道理的,但我所做的部分工作是试图强调纯HTML5可以做什么……所以闪电侠正好适合我。(尽管这对于任何制作“真正的”web应用程序的人来说都是一个非常有效的答案)在这种情况下,除非我想要涉及服务器,否则我看起来很不走运。谢谢!


当前回答

下面是一个将文件导出为ZIP的教程:

在开始之前,有一个库来保存文件,库的名字是filesver .js,你可以在这里找到这个库。让我们开始吧,现在,包括所需的库:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js"  type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>

现在复制这段代码,这段代码将下载一个带有Hello .txt文件的zip文件,其中包含Hello World的内容。如果一切正常,这将下载一个文件。

<script type="text/javascript">
    var zip = new JSZip();
    zip.file("Hello.txt", "Hello World\n");
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "file.zip");
    });
</script>

这将下载一个名为file.zip的文件。你可以在这里阅读更多:http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library

其他回答

try

let a = document.createElement('a'); a.href = "data:application/octet-stream,"+encodeURIComponent('我的数据'); a.download = 'myFile.json'; a.click ();//我们不添加'a'到DOM,所以不需要删除

如果你想下载二进制数据,看这里

更新

2020.06.14我将Chrome升级到83.0及以上SO代码片段停止工作(由于沙箱安全限制)-但JSFiddle版本工作-在这里

你可以用它来保存文本和其他数据:

function downloadFile(name, data) {
    let a = document.createElement("a");
    if (typeof a.download !== "undefined") a.download = name;
    a.href = URL.createObjectURL(new Blob([data], {
        type: "application/octet-stream"
    }));
    a.dispatchEvent(new MouseEvent("click"));
}

这个函数将创建一个Anchor元素,通过.download(如果支持的话)设置名称,分配一个从对象(url . createobjecturl)创建的url (.href),在本例中是一个Blob对象,并分派一个单击事件。简而言之:就好像你在点击一个下载链接。

示例代码

downloadFile("textfile.txt", "A simple text file");
downloadFile(
    "circle.svg",
    `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="42" />
    </svg>`
);
downloadFile(
    "utf8string.txt",
    new Uint8Array([85, 84, 70, 45, 56, 32, 115, 116, 114, 105, 110, 103]) // "UTF-8 string"
);

这个函数也接受File, Blob和MediaSource:

function downloadFile(name, data) {
    if (!(data instanceof File || data instanceof Blob || data instanceof MediaSource)) {
        return downloadFile(name, new Blob([data], {
            type: "application/octet-stream"
        }));
    }

    let a = document.createElement("a");
    if (typeof a.download !== "undefined") a.download = name;
    a.href = URL.createObjectURL(data);
    a.dispatchEvent(new MouseEvent("click"));
}

或者你可以使用两个函数:

function downloadFile(name, data) {
    return downloadObject(new Blob([data], {
        type: "application/octet-stream"
    }));
}

function downloadObject(name, object) {
    let a = document.createElement("a");
    if (typeof a.download !== "undefined") a.download = name;
    a.href = URL.createObjectURL(object);
    a.dispatchEvent(new MouseEvent("click"));
}

HTML5定义了一个窗口。saveAs(blob, filename)方法。目前任何浏览器都不支持它。但是,有一个名为filesver .js的兼容性库将此功能添加到大多数现代浏览器(包括Internet Explorer 10+)。Internet Explorer 10支持导航器。msSaveBlob(blob, filename)方法(MSDN),在filesver .js中用于Internet Explorer支持。

我写了一篇关于这个问题的详细博文。

您可以生成一个数据URI。但是,存在特定于浏览器的限制。

HTML5浏览器的简单解决方案…

function download(filename, text) {
    var pom = document.createElement('a');
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    pom.setAttribute('download', filename);

    if (document.createEvent) {
        var event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        pom.dispatchEvent(event);
    }
    else {
        pom.click();
    }
}

使用

download('test.txt', 'Hello world!');