如何启动客户端数据的文件下载并指定其文件名?

时间:2014-08-22 10:53:35

标签: javascript download

我一直在寻找一种方法来启动文件下载仅存在于用户浏览器上执行的代码中的数据(而不是从服务器启动下载),并指示文件名这个过程。

对StackOverflow的搜索发现了许多很有前途的帖子,这些帖子并不能满足我的需求。

This回答不兼容IE,并且无论如何都不允许指定文件名。

This问题提供了一些启动下载的方法,但允许指定文件名的答案不兼容IE并且需要用户交互,而其他答案不允许指定文件名。< / p>

有没有办法从JavaScript启动文件下载:

  • 下载客户端数据
  • 不要求用户手动启动下载
  • 允许指定下载文件的文件名

1 个答案:

答案 0 :(得分:2)

经过多次搜索并尝试各种方法,我能够提出以下建议。

tryAnchorDownload()方法应适用于现代版本的FireFox和Chrome,并且是提供的in this forum post代码的清理版本。

trySaveAsDownload()方法理论上应该适用于任何主要的现代浏览器,尽管Safari可能不尊重指定的文件名。它需要FileSaver.js库,某些浏览器可能需要Blob.js polyfill。

您可以像这样调用main函数:

initiateFileDownload(bytes, "myFile.txt");

其中bytes是文件的Uint8Array个字节。

function byteArrayToBase64(bytes) {
    var chArray = Array.prototype.map.call(bytes, 
                     function (byte) { return String.fromCharCode(byte); });

    return window.btoa(chArray.join(""));
}

var octetStreamMimeType = "application/octet-stream";

function tryAnchorDownload(fileBytes, fileName) {
    var aElement = document.createElement("a"),
        event;

    if ("download" in aElement) {
        aElement.setAttribute("download", fileName);
        aElement.href = "data:" + octetStreamMimeType + 
                        ";base64," + byteArrayToBase64(fileBytes);

        document.body.appendChild(aElement);
        event = document.createEvent("MouseEvents");
        event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0,
                             false, false, false, false, 0, null);
        aElement.dispatchEvent(event);
        document.body.removeChild(aElement);

        return true;
    }

    return false;
}

function trySaveAsDownload(fileBytes, fileName) {
    var blob;

    if (window.saveAs) {
        blob = new Blob([fileBytes], { type: octetStreamMimeType });

        saveAs(blob, fileName);

        return true;
    }

    return false;
}

// fileBytes is a Uint8Array
function initiateFileDownload(fileBytes, fileName) {
    return tryAnchorDownload(fileBytes, fileName) ||
           trySaveAsDownload(fileBytes, fileName);
}

可以找到上述byteArrayToBase64()函数的更全面(也可能更有效)的替代方法on MDN