David
David

Reputation: 4883

Opening a file with C# as a BLOB, and downloading with JS as a BLOB

I have a PDF on my .NET Core server, which I need to somehow send across the wire as a BLOB, so that my JS AJAX request can convert it back to a PDF so it can be downloaded.

The reason for the indirection is because the file comes from my API, which is only accessed through AJAX. Due to the need for a Bearer token, I can't just use a form behind the scenes, as there's no cookie for the site created. (Weird, I know, but that's how it is presently, and I'm not looking to change that part)

So, on my C# side, I've tried several variations, shown below. ApiResponse is just a container I use that holds a bool and a string (named message) so I can tell if the request was good or not.

These are what I've been trying

return new ApiResponse(true, File.ReadAllText(path));
return new ApiResponse(true, Convert.ToBase64String(File.ReadAllBytes(path)));
return new ApiResponse(true, JsonConvert.SerializeObject(File.ReadAllBytes(path)));

And on the JS side, in the same order to parse it back out, I have:

// Get the response in object form, since it's sent as an ApiResponse
const response = JSON.parse(xmlhttp.response);

const text = response.message;
const text = atob(response.message)
const text = JSON.parse(response.message)

I've also tried things like

const text = atob(JSON.parse(response.message))

Then, with the text I'm doing this:

const blob = new Blob([text], {type: "application/pdf"});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "file.pdf";

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

And this does correctly generate a file that's downloaded. However, that file is not valid: it's corrupted.

I'm pretty much stuck at this point, and I haven't been able to find something that goes from start to finish using this method to download files with Javascript. It's either the back side, or the front side, but never tied together.

So, how can I successfully send a PDF BLOB across the wire, and recreate it on the front end so it can be downloaded?

Upvotes: 1

Views: 4058

Answers (1)

David
David

Reputation: 4883

The easy answer to how to do the convert is don't.

Every modern browser supports base64 encoding natively, so there's no need to convert the data back to a BLOB before putting it into download.

Thus, the end code is:

const a = document.createElement("a");
a.href = "data:application/pdf;base64," + response.message;
a.download = "file.pdf";

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

Upvotes: 1

Related Questions