mad scientist mad scientist - 10 months ago 367
Javascript Question

jsPDF - send pdf to server ends up corrupted

I generate a pdf with text and images using javascript jsPDF library. Then I want to send the file to server in order to send an email with it. The problem is that the file that arrives on server is corrupted and can't be opened or I can't see the images on the pdf.

My code:

var pdf = btoa(doc.output());

- this gives an error:
Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

var pdf = btoa(encodeURIComponent(doc.output()));
var data = new FormData();
data.append("data" , pdf);
var xhr = new XMLHttpRequest(); 'post', '/url', true );

I also tried other things like:

var pdf = btoa(encodeURIComponent(doc.output('blob')));
- the file can't be opened

var pdf = btoa(doc.output('blob'));
- the file can't be opened

var pdf = btoa(unescape(encodeURIComponent(doc.output())));
- the file will open but the images are some grey lines

PS: I am using Laravel 5. Server code:

$data = base64_decode($_POST['data']);
$fname = "test.pdf";
$file = fopen("pdf/" .$fname, 'w');
fwrite($file, $data);


js code:

var blob = doc.output('blob');
var fd = new FormData();
fd.append('data', blob);
type: 'POST',
url: '/url',
data: fd,
processData: false,
contentType: false
}).done(function(data) {

server code:

public_path() . '/test.pdf'
return "Pdf was successfully saved.";
} else {
return "No Data Sent";

Answer Source

btoa is messed up with the ascii byte range... javascript can't hold all character. That's the reason for why you shouldn't use FileReader's readAsBinaryString either... Handle binary the right way, not as string or ~3x larger base64 string, but as a blob, ArrayBuffer or a typed array and it will turn out fine

var blob = doc.output('blob')