使用JavaScript从浏览器将二进制数据保存为文件

69

我正在使用 angularJS 开发一个商业应用程序。我的一个服务方法返回一个 byte[](其中包括 PDF 文件内容),现在我需要使用 JavaScript 将此文件下载为 PDF 到客户端计算机。

如何使用 HTML5 API 或任何 JavaScript API 实现?

我已经使用了 window.atob(base64String)

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IDQ1MiAzOTUgMzE0IDQ2MCAzMTQgNDk4IDUwNiA1MDYgDTUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiANNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgMjI2IA0zMjUgNDk4IDUwNiA0OTggNTA2IDQ5OCA0OTggMzkyIDgzNCA0MDIgNTEyIDQ5OCAzMDYgNTA2IDM5NCAzMzggDTQ5OCAzMzUgMzM0IDI5MSA1NDkgNTg1IDI1MiAzMDcgMjQ2IDQyMiA1MTIgNjM2IDY3MSA2NzUgNDYzIDU3OCANNTc4IDU3OCA1NzggNTc4IDU3OCA3NjMgNTMzIDQ4OCA0ODggNDg4IDQ4OCAyNTEgMjUxIDI1MSAyNTEgNjI0IA02NDUgNjYyIDY2MiA2NjIgNjYyIDY2MiA0OTggNjYzIDY0MSA2NDEgNjQxIDY0MSA0ODcgNTE2IDUyNyA0NzkgDTQ3OSA0NzkgNDc5IDQ3OSA0NzkgNzcyIDQyMiA0OTcgNDk3IDQ5NyA0OTcgMjI5IDIyOSAyMjkgMjI5IDUyNSANNTI1IDUyNyA1MjcgNTI3IDUyNyA1MjcgNDk4IDUyOSA1MjUgNTI1IDUyNSA1MjUgNDUyIDUyNSA0NTIgXQ0vRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyANL0ZvbnREZXNjcmlwdG9yIDkgMCBSIA0+Pg1lbmRvYmoNOSAwIG9iag08PA0vVHlwZSAvRm9udERlc2NyaXB0b3IgDS9Bc2NlbnQgNzUwIA0vQ2FwSGVpZ2h0IDUwMCANL0Rlc2NlbnQgLTI1MCANL0ZsYWdzIDMyIA0vRm9udEJCb3ggWyAtNTAzIC0zMDcgMTI0MCA5NjQgXSANL0ZvbnROYW1lIC9DYWxpYnJpIA0vSXRhbGljQW5nbGUgMCANL1N0ZW1WIDAgDT4+DWVuZG9iag0xMCAwIG9iag08PA0vVHlwZSAvRm9udCANL0Jhc2VGb250IC9DYWxpYnJpLEJvbGQgDS9TdWJ0eXBlIC9UcnVlVHlwZSANL05hbWUgL0YxIA0vRmlyc3RDaGFyIDMyIA0vTGFzdENoYXIgMjU1IA0vV2lkdGhzIFsyMjYgMzI1IDQzOCA0OTggNTA2IDcyOSA3MDQgMjMzIDMxMSAzMTEgNDk4IDQ5OCAyNTcgMzA2IDI2NyA0MjkgNTA2IA01MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiAyNzUgMjc1IDQ5OCA0OTggNDk4IDQ2MyA4OTggDTYwNSA1NjAgNTI5IDYzMCA0ODcgNDU4IDYzNyA2MzAgMjY2IDMzMSA1NDYgNDIyIDg3NCA2NTggNjc2IDUzMiANNjg2IDU2MiA0NzIgNDk1IDY1MiA1OTEgOTA2IDU1MCA1MTkgNDc4IDMyNCA0MjkgMzI0IDQ5OCA0OTggMzAwIA00OTMgNTM2IDQxOCA1MzYgNTAzIDMxNiA0NzQgNTM2IDI0NSAyNTUgNDc5IDI0NSA4MTMgNTM2IDUzNyA1MzYgDTUzNiAzNTUgMzk4IDM0NiA1MzYgNDczIDc0NSA0NTkgNDczIDM5NyAzNDMgNDc1IDM0MyA0OTggNTA2IDUwNiANNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IA01MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiA1MDYgNTA2IDUwNiAyMjYgDTMyNSA0OTggNTA2IDQ5OCA1MDYgNDk4IDQ5OCA0MTQgODM0IDQxNiA1MzggNDk4IDMwNiA1MDYgMzkwIDM0MiANNDk4IDMzNyAzMzUgMzAwIDU2MyA1OTcgMjY3IDMwMyAyNTIgNDM1IDUzOCA2NTcgNjkwIDcwMSA0NjMgNjA1IA02MDUgNjA1IDYwNSA2MDUgNjA1IDc3NSA1MjkgNDg3IDQ4NyA0ODcgNDg3IDI2NiAyNjYgMjY2IDI2NiA2MzkgDTY1OCA2NzYgNjc2IDY3NiA2NzYgNjc2IDQ5OCA2ODAgNjUyIDY1MiA2NTIgNjUyIDUxOSA1MzIgNTU0IDQ5MyANNDkzIDQ5MyA0OTMgNDkzIDQ5MyA3NzQgNDE4IDUwMyA1MDMgNTAzIDUwMyAyNDUgMjQ1IDI0NSAyNDUgNTM2IA01MzYgNTM3IDUzNyA1MzcgNTM3IDUzNyA0OTggNTQzIDUzNiA1MzYgNTM2IDUzNiA0NzMgNTM2IDQ3MyBdDS9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nIA0vRm9udERlc2NyaXB0b3IgMTEgMCBSIA0+Pg1lbmRvYmoNMTEgMCBvYmoNPDwNL1R5cGUgL0ZvbnREZXNjcmlwdG9yIA0vQXNjZW50IDc1MCANL0NhcEhlaWdodCA1MDAgDS9EZXNjZW50IC0yNTAgDS9GbGFncyAzMiANL0ZvbnRCQm94IFsgLTUxOSAtMzA2IDEyNDAgOTcxIF0gDS9Gb250TmFtZSAvQ2FsaWJyaSxCb2xkIA0vSXRhbGljQW5nbGUgMCANL1N0ZW1WIDAgDT4+DWVuZG9iag0xMiAwIG9iag08PA0vVHlwZSAvQ2F0YWxvZyANL1BhZ2VzIDMgMCBSIA0vUGFnZU1vZGUgL1VzZU5vbmUgDS9WaWV3ZXJQcmVmZXJlbmNlcyA8PA0vSGlkZVRvb2xiYXIgZmFsc2UgDS9IaWRlTWVudWJhciBmYWxzZSANL0hpZGVXaW5kb3dVSSBmYWxzZSANL0ZpdFdpbmRvdyBmYWxzZSANL0NlbnRlcldpbmRvdyBmYWxzZSANL0Rpc3BsYXlEb2NUaXRsZSBmYWxzZSANL05vbkZ1bGxTY3JlZW5QYWdlTW9kZSAvVXNlTm9uZSANPj4NPj4NZW5kb2JqDXhyZWYNMCAxMw0wMDAwMDAwMDAwIDY1NTM1IGYgDTAwMDAwMDAwNDggMDAwMDAgbiANMDAwMDAwMDIyMCAwMDAwMCBuIA0wMDAwMDAwMjU2IDAwMDAwIG4gDTAwMDAwMDAzMjEgMDAwMDAgbiANMDAwMDAwMDUwNCAwMDAwMCBuIA0wMDAwMDAxODc3IDAwMDAwIG4gDTAwMDAwMDIwNDggMDAwMDAgbiANMDAwMDAwMjIyNiAwMDAwMCBuIA0wMDAwMDAzMzEyIDAwMDAwIG4gDTAwMDAwMDM0OTEgMDAwMDAgbiANMDAwMDAwNDU4NCAwMDAwMCBuIA0wMDAwMDA0NzY5IDAwMDAwIG4gDXRyYWlsZXINPDwNL1NpemUgMTMgDS9Sb290IDEyIDAgUiANL0luZm8gMSAwIFIgDS9JRFs8QzFEMTBFNDk4OTQ2QkU0RUJFODUzRUNCRDk4OEM1Q0Q+PEMxRDEwRTQ5ODk0NkJFNEVCRTg1M0VDQkQ5ODhDNUNEPl0NPj4Nc3RhcnR4cmVmDTUwMjMNJSVFT0YN

但出现了以下错误:Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.


可能是重复的问题:使用HTML5/Javascript生成并保存文件 - T.Todua
4个回答

93
如果浏览器支持锚元素中的download属性,则这是可能的。
var sampleBytes = new Int8Array(4096);

var saveByteArray = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, name) {
        var blob = new Blob(data, {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = name;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

saveByteArray([sampleBytes], 'example.txt');


JSFiddle: http://jsfiddle.net/VB59f/2


2
在Chrome中出现以下错误:TypeError: Failed to construct 'Blob': The 1st argument is neither an array, nor does it have indexed properties. - Ravi Mittal
@RaviMittal -- 你正在向数据参数提供什么? - Syntax
服务返回的是byte[],但我认为它已经转换成了base64字符串。 - Ravi Mittal
@Syntax 如何将base64转换为数组。 - Ravi Mittal
我正在使用iOS 12。锚标签没有下载属性。我该怎么办? - Aosis
显示剩余8条评论

63
使用 FileSaver.js。它支持ChromeEdgeFirefoxIE 10+并且可能需要一些“polyfills”来支持IE < 10,请参见Note 4)。FileSaver.js在不支持本地保存的浏览器中实现了saveAs() FileSaver接口:
     https://github.com/eligrey/FileSaver.js 压缩版本大小小于2.5KB,压缩后小于1.2KB。
使用方法:
/* TODO: replace the blob content with your byte[] */
var blob = new Blob([yourBinaryDataAsAnArrayOrAsAString], {type: "application/octet-stream"});
var fileName = "myFileName.myExtension";
saveAs(blob, fileName);

在一些浏览器中可能需要使用 Blob.js (请参见Note 3)。 Blob.js 在那些不原生支持它的浏览器中实现了 W3C Blob 接口,是一个跨浏览器的实现:
     https://github.com/eligrey/Blob.js

如果您有超过blob大小限制的文件,请考虑使用StreamSaver.js

Complete example:

/* Two options
 * 1. Get FileSaver.js from here
 *     https://github.com/eligrey/FileSaver.js/blob/master/FileSaver.min.js -->
 *     <script src="FileSaver.min.js" />
 *
 * Or
 *
 * 2. If you want to support only modern browsers like Chrome, Edge, Firefox, etc., 
 *    then a simple implementation of saveAs function can be:
 */
function saveAs(blob, fileName) {
    var url = window.URL.createObjectURL(blob);

    var anchorElem = document.createElement("a");
    anchorElem.style = "display: none";
    anchorElem.href = url;
    anchorElem.download = fileName;

    document.body.appendChild(anchorElem);
    anchorElem.click();

    document.body.removeChild(anchorElem);

    // On Edge, revokeObjectURL should be called only after
    // a.click() has completed, atleast on EdgeHTML 15.15048
    setTimeout(function() {
        window.URL.revokeObjectURL(url);
    }, 1000);
}

(function() {
    // convert base64 string to byte array
    var byteCharacters = atob("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");
    var byteNumbers = new Array(byteCharacters.length);
    for (var i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    var byteArray = new Uint8Array(byteNumbers);
    
    // now that we have the byte array, construct the blob from it
    var blob1 = new Blob([byteArray], {type: "application/octet-stream"});

    var fileName1 = "cool.gif";
    saveAs(blob1, fileName1);

    // saving text file
    var blob2 = new Blob(["cool"], {type: "text/plain"});
    var fileName2 = "cool.txt";
    saveAs(blob2, fileName2);
})();

JSFiddle 在这里:页面加载时应下载两个小文件 - 一个二进制文件(GIF)和一个文本文件。更新:StackOverflow的Run code snippet不再支持下载文件,因为默认情况下沙盒在较新的浏览器版本中不允许下载文件。

已在Chrome、Edge、Firefox和IE 11上测试(使用FileSaver.js支持IE 11)。
您还可以从canvas元素中保存。请参见https://github.com/eligrey/FileSaver.js#saving-a-canvas

演示:https://eligrey.com/demos/FileSaver.js/

作者的博文http://eligrey.com/blog/post/saving-generated-files-on-the-client-side

注1: 浏览器支持:https://github.com/eligrey/FileSaver.js#supported-browsers

注2: 在“Window”上执行“atob”失败

注3: 不支持Blob的浏览器的Polyfill:https://github.com/eligrey/Blob.js
请参阅http://caniuse.com/#search=blob

注4: IE<10的支持(我没有测试这部分):
                https://github.com/eligrey/FileSaver.js#ie--10
                https://github.com/eligrey/FileSaver.js/issues/56#issuecomment-30917476

Downloadify是一个基于Flash的Polyfill,用于支持IE6-9:https://github.com/dcneiner/downloadify(但我通常不建议使用基于Flash的解决方案。)
演示如何使用DownloadifyFileSaver.js来支持IE6-9:http://sheetjs.com/demos/table.html

Note 5: 在JavaScript中从Base64字符串创建BLOB

Note 6: FileSaver.js示例:https://github.com/eligrey/FileSaver.js#examples


请注意,Safari对此功能的支持非常差。在Safari中尝试使用FileSaver.js演示文稿时,经常会创建一个新的选项卡而不是保存文件!https://eligrey.com/demos/FileSaver.js/ - Colin D
@ColinD:同意。支持Safari似乎并不容易:http://stackoverflow.com/questions/36444507/how-to-show-save-file-dialog-in-safari - Sachin Joseph
@ColinD:Safari的一个解决方法是:1)使用createObjectURLhref属性中创建一个带有文件内容的锚元素。2)现在请用户右键单击并保存文件。 - Sachin Joseph
@Sachin Joseph - 这个能用来将一个二进制值转换成它最初的Excel格式吗?我保存了一个由用户上传到数据库的Excel文件(我使用SheetJS将Excel文件转换成JSON,然后使用btoa将其转换成Base64)。我需要检索保存的二进制对象,将其转换回Excel,然后使用JavaScript将其显示给用户。 - Roger Dodger
1
@RogerDodger 在 SheetJs 的网站上有一个演示,它使用 FileSaver.js 和 SheetJs 将数据导出为 Excel 格式:http://sheetjs.com/demos/table.html - Sachin Joseph
显示剩余2条评论

5

尝试

let bytes = [65,108,105,99,101,39,115,32,65,100,118,101,110,116,117,114,101];

let base64data = btoa(String.fromCharCode.apply(null, bytes));

let a = document.createElement('a');
a.href = 'data:;base64,' + base64data;
a.download = 'binFile.txt'; 
a.click();

我在这里将二进制数据转换为base64(如果需要转换更大的数据,请使用此方法)- 下载时,浏览器会自动解码并将原始数据保存到文件中。2020.06.14 我升级了Chrome至83.0及以上版本,因为沙箱安全限制,SO代码片段停止工作 - 但是JSFiddle版本可以正常工作 - 此处


2
要完成此任务,可以使用download.js库。以下是库文档中的示例:最初的回答。
download("data:image/gif;base64,R0lGODlhRgAVAIcAAOfn5+/v7/f39////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH5BAAAAP8ALAAAAABGABUAAAj/AAEIHAgggMGDCAkSRMgwgEKBDRM+LBjRoEKDAjJq1GhxIMaNGzt6DAAypMORJTmeLKhxgMuXKiGSzPgSZsaVMwXUdBmTYsudKjHuBCoAIc2hMBnqRMqz6MGjTJ0KZcrz5EyqA276xJrVKlSkWqdGLQpxKVWyW8+iJcl1LVu1XttafTs2Lla3ZqNavAo37dm9X4eGFQtWKt+6T+8aDkxUqWKjeQUvfvw0MtHJcCtTJiwZsmLMiD9uplvY82jLNW9qzsy58WrWpDu/Lp0YNmPXrVMvRm3T6GneSX3bBt5VeOjDemfLFv1XOW7kncvKdZi7t/S7e2M3LkscLcvH3LF7HwSuVeZtjuPPe2d+GefPrD1RpnS6MGdJkebn4/+oMSAAOw==", "dlDataUrlBin.gif", "image/gif");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接