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

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

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

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


当前回答

保存大文件

Long data URIs can give performance problems in browsers. Another option to save client-side generated files, is to put their contents in a Blob (or File) object and create a download link using URL.createObjectURL(blob). This returns an URL that can be used to retrieve the contents of the blob. The blob is stored inside the browser until either URL.revokeObjectURL() is called on the URL or the document that created it is closed. Most web browsers have support for object URLs, Opera Mini is the only one that does not support them.

强制下载

If the data is text or an image, the browser can open the file, instead of saving it to disk. To cause the file to be downloaded upon clicking the link, you can use the the download attribute. However, not all web browsers have support for the download attribute. Another option is to use application/octet-stream as the file's mime-type, but this causes the file to be presented as a binary blob which is especially user-unfriendly if you don't or can't specify a filename. See also 'Force to open "Save As..." popup open at text link click for pdf in HTML'.

指定文件名

如果blob是用File构造函数创建的,你也可以设置一个文件名,但只有少数web浏览器(包括Chrome和Firefox)支持File构造函数。文件名也可以指定为download属性的参数,但这需要考虑大量的安全问题。Internet Explorer 10和11提供了自己的方法msSaveBlob来指定文件名。

示例代码

var file; var data = []; data.push("This is a test\n"); data.push("Of creating a file\n"); data.push("In a browser\n"); var properties = {type: 'text/plain'}; // Specify the file's mime-type. try { // Specify the filename using the File constructor, but ... file = new File(data, "file.txt", properties); } catch (e) { // ... fall back to the Blob constructor if that isn't supported. file = new Blob(data, properties); } var url = URL.createObjectURL(file); document.getElementById('link').href = url; <a id="link" target="_blank" download="file.txt">Download</a>

其他回答

看看Doug Neiner的downadify,这是一个基于Flash的JavaScript界面。

downloadadify是一个很小的JavaScript + Flash库,可以在浏览器中生成和保存文件,而不需要服务器交互。

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!');
function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}

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

好的,创建一个data:URI对我来说确实很有用,感谢Matthew和Dennkster指出了这个选项!以下是我的基本做法:

1)获取所有的内容到一个名为“content”的字符串(例如,通过最初创建它或通过读取已构建页面的标签的innerHTML)。

2)构建数据URI:

uriContent = "data:application/octet-stream," + encodeURIComponent(content);

根据浏览器类型等会有长度限制,但例如Firefox 3.6.12至少可以工作到256k。在Base64中编码而不是使用encodeURIComponent可能会使事情更有效,但对我来说这是可以的。

3)打开一个新窗口,“重定向”到这个URI提示下载位置的JavaScript生成页面:

newWindow = window.open(uriContent, 'neuesDokument');

就是这样。