从 JavaScript 中的字节下载文件

我想从 AJAX 响应中下载字节形式的文件。

我试着在 Blob的帮助下这样做:

var blob=new Blob([resultByte], {type: "application/pdf"});
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.pdf";
link.click();

它实际上正在下载 pdf 文件,但文件本身已损坏。

我该怎么做呢?

157590 次浏览

Set Blob type at Blob constructor instead of at createObjectURL

var blob = new Blob([resultByte], {type: "application/pdf"});
var link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = "myFileName.pdf";
link.click();

I asked the question long time ago, so I might be wrong in some details.

It turns out that Blob needs array buffers. That's why base64 bytes need to be converted to array buffers first.

Here is the function to do that:

function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes;
}

Here is my function to save a pdf file:

function saveByteArray(reportName, byte) {
var blob = new Blob([byte], {type: "application/pdf"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
};

Here is how to use these two functions together:

var sampleArr = base64ToArrayBuffer(data);
saveByteArray("Sample Report", sampleArr);

You just need to add one extra line and it should work. Your response is byte array from your server application

var bytes = new Uint8Array(resultByte); // pass your byte response to this constructor


var blob=new Blob([bytes], {type: "application/pdf"});// change resultByte to bytes


var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.pdf";
link.click();

Easiest way would be converting bytes to the base64 format and construct link as below

let link=document.createElement('a');
const mimeType = "application/pdf";
link.href=`data:${mimeType};base64,${base64Str}`;
link.download="myFileName.pdf";
link.click();

Link can be generated on backend side and retrieved from the response.
File bytes can be read as base64 string in Python as following:

with open("my-file.pdf", "rb") as file:
base46_str = base64.b64encode(file.read()).decode("utf-8")