Download base64 PDF - javascript

I am receiving from the server the following response:
Object {
$type: "base64",
$data: "JVBERi0xLjQK..."
}
I try to autodownload it with FileSaver.js
let arrayBuffer = atob(response.$data);
let blob = new Blob([arrayBuffer], {type: "application/pdf;charset=utf-8"});
saveAs(blob, 'myfile.pdf');
A PDF is generated, and downloads (it has the same page number as the original on the server), but is empty.
However this works:
window.open("data:application/pdf;base64," + response.$data);
It opens the PDF with its content.

Related

Can't convert base64 sent from iPhone to server

I have a problem when my site sends converted audio in base64 to my server it converts the base64 in audio format and works with it.
But when the site is accessed from an iPhone and the recording arrives at the server, then a one-second recording after converting remains on the server. On all other devices and operation systems, everything comes and is processed normally. How can this be fixed?
This converter's python code on server:
...
data = json.loads(await request.body())
file = open(f'{UPLOAD_DIRECTORY}/' + ID_file + '.wav', "wb")
file.write(base64.b64decode(data['audio']))
file.close()
...
This converter's JS code on site:
...
var reader = new window.FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = function() {
base64 = reader.result;
base64 = base64.split(',')[1];
...

Receiving blank PDF from BLOB data in my database

I'm storing my PDF files into my SQL database using C# and using BLOB(long) as my SQL datatype.
C# code:
Convert PDF to bytes
FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length));
Storing bytes into the database
string query = "INSERT INTO invoices (data, dateTime, invoiceNo, ni) VALUES (#d, #dt, #in, #ni)";
var cmd = new MySqlCommand(query, dbCon.Connection);
cmd.Parameters.AddWithValue("#d", bytes);
cmd.Parameters.AddWithValue("#dt", dateTime);
cmd.Parameters.AddWithValue("#in", invoiceNo);
cmd.Parameters.AddWithValue("#ni", ni);
try
{
cmd.ExecuteNonQuery();
Database table structure (Using longblob):
Now, that is all done from the client application and there are multiple records, on the web side, i'm trying to pull that blob data from the database and convert it back to PDF and download it. It all works great apart from the PDF is blank even though there is an average of 170kb per PDF.
Web side:
I'm getting the blob data from the database and trying to convert it into a PDF file using this JavaScript function:
function convertInvoiceBlob(fileName, resData) {
var newBlob = new Blob([resData], {type: "application/pdf"});
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
const data = window.URL.createObjectURL(newBlob);
var link = document.createElement("a");
link.href = data;
link.download= fileName;
link.click();
setTimeout(function(){
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(data);
}, 100);
}
However I'm receiving a blank PDF. I'm not quite sure which part I have mistakes at, whether its storing it into the database incorrectly or receiving the data and converting it incorrectly.

How to check if the PDF is blank in Angular JS?

Here is the code that loads the pdf file and download it:
$http.get('/retrievePDFFile', {responseType: 'arraybuffer'})
.success(function (data) {
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.open(fileURL);
});
For some reason, I want to check if the pdf is not blank before it gets downloaded. I don't want to download an empty pdf.
Or someone can tell me, how to convert PDF Stream to json or text, would be great.

Decode a pickled file that has been encoded as a Blob

Overview:
I am trying to get save/load functionality working as part of a web app I am building, but cannot properly reload a file after I've downloaded it.
Backend:
I have a list a of lists in python that looks something like
[[bytes, bytes, int, list, list, str], [...], [...], etc].
This is the data I care about. I then pickle it using
with open(file_path, 'wb') as fp:
pickle.dump(save_this_arr, fp)
and send it using Flask's send_file:
return send_file(file_path, as_attachment=True)
Frontend:
On the front end, I am creating a blob, encoding a data url, and then setting it as the src of a hidden <iframe>:
let blob = new Blob([response.data], { type: "application/octet-stream" });
let url = window.URL.createObjectURL(blob);
self.downloader.src = url
This works fine and gets me a file that I can re-upload.
Problem:
I am getting stuck on how to properly decode the URL so that I can pickle.load the result. The two links below seem like they're what I need, but I'm getting UnicodeDecodeErrors when I apply it to my code.
Current Attempt:
with open(file_path, "rb") as fid:
contents = fid.read()
data = urllib.parse.parse_qs(contents, encoding='utf-16')
with open(file_path, 'wb') as fid:
fid.write(text)
with open(file_path, 'rb') as fid:
myList = pickle.load(fid)
EDIT:
The original question asked about decoding a url because I misunderstood what window.URL.createObjectURL(blob) was doing. From this blog post, I realized that we are actually creating a reference to an in-memory blob. So what I actually want to do is read a Blob in Python.
References:
Url decode UTF-8 in Python
decoding URL encoded byte stream data in python
I'm not sure why I was unable to decode the blob directly, but encoding to a base64 string before writing the file works.
Backend (writing to disk):
import base64
with open(file_path, 'wb') as fp:
data = pickle.dumps(save_this_arr)
encoded = base64.b64encode(data)
fp.write(encoded)
Frontend (copied from question - no change):
let blob = new Blob([response.data], { type: "application/octet-stream" });
let url = window.URL.createObjectURL(blob);
self.downloader.src = url
Backend (reading from disk):
with open(file_path, "rb") as fid:
contents = fid.read()
decoded = base64.b64decode(contents)
myList = pickle.loads(decoded)

Save blob content to file

I'm working into a project to encrypt/decrypt files in JavaScript. To save the encrypted/decrypted file in disk, I'm using blob. All the process is working, the files get encrypted (and some tests show-me that decrypted too) correctly. And I can save even large files with the blob method (I was using URI data before, and it was causing browser crash errors when files size more than 1MB). But for some reason, I can't save the decrypted blob content into a file correctly. When it's a TXT file, I get this in the beginning of the file content:
data:text/plain;base64,
and it continues with the text content encoded in base64. I need it to be saved as original file, not in base64. When I decrypt an exe file, it's corrupted, so if I open it into some text editor, I get:
data:application/x-msdownload;base64,
Again, looks like the file is getting saved in base64 and with this header attached. Here's my code to create/save the content of blob (on decrypt routine):
reader.onload = function(e){
var decrypted = CryptoJS.AES.decrypt(e.target.result, password)
.toString(CryptoJS.enc.Latin1);
var blob = new Blob([decrypted]);
var objectURL = window.URL.createObjectURL(blob);
if(!/^data:/.test(decrypted)){
alert("Invalid pass phrase or file! Please try again.");
return false;
}
a.attr('href','' + objectURL);
a.attr('download', file.name.replace('.encrypted',''));
step(4);
};
reader.readAsText(file);
}
How can I save the files with the original content? And not header+base64 encode?

Categories

Resources