Pdf image corrupts pdf sent to server

I am creating a PDF document in a web application with jsPDF, sending this document to Perl and having a Perl email address and it works fine. However, when I add an image to a PDF, it no longer works, because Adobe Reader says the file is damaged. The application is huge, so there is a stub with the same corresponding code, which acts the same way:

HTML:

<!DOCTYPE html> <html> <head> <script src="https://<myserver>/js/jquery.js"></script> <script src="https://<myserver>/js/jspdf.js"></script> <script src="https://<myserver>/js/jspdf.plugin.addimage.js"></script> <script src="https://<myserver>/test/pdf.js"></script> </head> <body> <input type="submit" id="go"> </body> </html> 

JS:

 $(document).ready(function() { $('#go').on('click',function() { //create PDF var imgData = 'data:image/jpeg;base64,<dataurlencoded image string>'; var doc = new jsPDF('p','pt','a4'); doc.addImage(imgData, 'JPEG', 22, 22, 138, 28); doc.text(30, 120, 'Lorem Ipsum!'); var perl_pdf = doc.output(); //send PDF to perl and have perl email it $.ajax({ type: "POST", url: "https://<myserver>/cgi-bin/pdf.pl", contentType: "application/x-www-form-urlencoded; charset=UTF-8", dataType: "json", data: "perl_pdf="+encodeURIComponent(perl_pdf), error: function(XMLHttpRequest, textStatus, errorThrown) { alert("error: "+ XMLHttpRequest.responseText + ", textStatus: " + textStatus + ", errorThrown: " + errorThrown); }, success: function(data){ alert("Success: "+data.success); } }); }); }); 

Perl:

 #!d:/perl/bin/perl.exe -w use strict; use warnings; use CGI qw(:all); use MIME::Lite; use MIME::Base64; my $q = CGI->new(); my $pdf_doc = $q->param('perl_pdf'); open (OUTFILE, '>pdf.pdf') or die "Could not open file"; binmode(OUTFILE); print OUTFILE decode_base64($pdf_doc); close OUTFILE; my $from_address = '<from_address>'; my $to_address = '<to_address>'; my $mail_host = '<smtp_server>'; my $subject = 'PDF Test'; my $message_body = "The PDF is attached...\n\n"; my $my_file = 'pdf.pdf'; my $out_file = 'test.pdf'; my $msg = MIME::Lite->new ( From => $from_address, To => $to_address, Subject => $subject, Type => 'multipart/mixed') or die "Cannot create multipart container: $!\n"; $msg->attach ( Type => 'TEXT', Data => $message_body) or die "Cannot attach text: $!\n"; $msg->attach ( Type => 'application/pdf', Path => $my_file, Filename => $out_file, Disposition => 'attachment') or die "Cannot attach file: $!\n"; MIME::Lite->send('smtp', $mail_host, Timeout=>60); $msg->send; my $json = qq{{"success" : "This worked"}}; print $q->header(-type => "application/json", -charset => "utf-8"); print $json; 

If I replaced the Ajax call and created the output with ...

 doc.output('dataurlnewwindow',{}); 

... then it displays correctly on a new browser tab, so I know that the image is inserted correctly. From what I found in my searches, this is apparently some encoding problem, but I have not yet found a solution to the problem. How can I get a PDF document with an image sent to Perl on the server successfully so that it is not damaged?

+3
source share
3 answers

I found a problem. Before adding the image to PDF, sending the file to Perl worked without encoding, apparently due to the absence (or absence of pertinent) binary information lost when sending the line. Of course, adding the image added very important binary information to the string, which could not be sent in the urlencoded message. Encoding / decoding should have taken care of this, but ...

I tried many different Base64 encoding / decoding methods, but my file was still corrupted. I finally stumbled upon a similar problem when someone mentioned that sending a string as part of a URL would convert the + signs to spaces. I removed the decoding on the Perl side to see what the encoded string looked like, and there really were a few spaces all over the string. Convert them back using

 $pdf_doc =~ s/ /+/g; 

before Perl writes the corrected problem to the file. Now the file can be connected to Adobe on the server side.

0
source

This issue is resolved in the latest version of JSPDF. If you submit a PDF with images to the server as form data using xmlhttprequest.send or as part of an ajax call.

use jsPDF.output('blob') instead of jsPDF.output() .

This will not damage the pdf file when sent to the server.

+1
source

OK, this probably won't help you because you are using Windows, just a demo:

My perl test script is called app.pl :

 #!/usr/bin/env perl use strict; use warnings; use CGI qw(:all); my $q = CGI->new(); my $pdf_doc = $q->param('perl_pdf'); open (my $fp, '>', 'pdf.pdf') or die "Could not open file"; print $fp $pdf_doc; close $fp; print "OK\n"; 

You have a pdf file called x.pdf .

 $ ls -l x.pdf -rw-r--r--@ 1 jm staff 100838 18 mar 19:20 x.pdf 

Running a simple test web server on server 3000

 plackup --port 3000 -MPlack::App::WrapCGI -e 'Plack::App::WrapCGI->new( script => "./app.pl", execute => 1)->to_app' 

He speaks:

 HTTP::Server::PSGI: Accepting connections at http://0:3000/ 

From another terminal sending a base64 encoded file using the curl command

 $ curl -i -F perl_pdf="$(base64 < x.pdf)" 0:3000/ 

Answer:

 HTTP/1.0 200 OK Date: Tue, 18 Mar 2014 20:15:40 GMT Server: HTTP::Server::PSGI Content-Length: 3 OK 

the server says:

 127.0.0.1 - - [18/Mar/2014:21:06:00 +0100] "POST / HTTP/1.1" 200 3 "-" "curl/7.35.0" 

and saved the pdf.pdf file pdf.pdf file has base64 encoded content.

 $ ls -la pdf.pdf -rw-r--r-- 1 jm staff 134452 18 mar 21:06 pdf.pdf 

decode it

 $ base64 -D < pdf.pdf >decoded.pdf 

and compare with the original

 $ cmp decoded.pdf x.pdf $ ls -la decoded.pdf -rw-r--r-- 1 jm staff 100838 18 mar 21:18 decoded.pdf 

it makes no difference - sending pdf is successful.

Unfortunately, it will not help you anymore, because:

  • You are using windows
  • and i don't know javascript ...

Consider to check:

0
source

All Articles