pdf (mpdf) file gets corrupted in javascript - javascript

I have a web app, where pdfs need to be generated dynamically. Data is gathered in javascript and send with a post request to the server. Here mpdf is used to generate a pdf. If I save the file locally: php $mpdf->Output($filename, \Mpdf\Output\Destination::FILE); it works.
But if I send it to the browser php $mpdf->Output($filename, \Mpdf\Output\Destination::DOWNLOAD); and take the output in the jquery callback to do the following (borrowed from https://nehalist.io/downloading-files-from-post-requests/):
jQuery.post(my_axax_url, data, function(data) {
var blob = new Blob([data], { type: 'application/pdf' });
var l = document.createElement('a');
l.href = window.URL.createObjectURL(blob);
l.download = 'test.pdf';
document.body.appendChild(l);
l.click();
});
The downloaded pdf is empty (blank page), and has corrupted author information (that makes it look, like an encoding problem). I ran https://www.datalogics.com/products/pdftools/pdf-checker/, which only gave me it the javascript generated pdf is a "Damaged document".
I hope, that this is an easy problem. I am used to php and text documents, not pdf.
Thanks!

Try adding the following to the start of your php script, it may be some sort of encoding issue:
ob_clean();
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="test.pdf"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');

Related

Unable to upload pdf file: Php

The issue I'm facing is, I get the following error while trying to upload some pdfs your upload file is not PDF file. However, this error doesn't show up for all pdfs, it's only for some pdf files I get this error.
<?php
$error = $_FILES['fileToUpload']['error'];
//get upload file type
$type = $_FILES['fileToUpload']['type'];
$action = "upload";
//get file name
$picname = $_FILES['fileToUpload']['name'];
$nameArray = explode(".", $picname);
if {
//check files
//filetoUpload code
}
?>
The issue is that, in the url: '../controller/uploadFile.php' even if the file is PDF, $type = $_FILES['fileToUpload']['type']; will return empty and then it will go into the condition else if($type !="application/pdf" ) and pop up the alert your upload file is not PDF file.. Like I said, this issue is with most of the pdf file. However, some pdf files manage to get uploaded without any issue and if a pdf file gets uploaded, then $type will be application/pdf.
Your input will be highly appriciated.
---UPDATE---
The issue is with $_FILES, it's not fetching the pdf file details for some reason
The issue has been resolved. I checked '$error= $_FILES['fileToUpload']['error']; and the value was returning 1
Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.```
You could better check the extension, this also prevents malicious users to upload exe or zip files when they provide the header Content-Type: application/pdf. Also not all browsers/api libraries specify a Content-Type.
If your filename does not contain a path, check it with a regex so people cannot upload files to directories they shouldn't (ex ../../cache/exe). use for example
preg_match("/^[a-zA-Z0-9_+\\- ]+\\.pdf$/", $filename) to check if it is a pdf.
Do never do unlink('files/' . $filename); when $filename could be anything submitted by the user. Delete ../index.php could destroy your server.

How to save PDF file in JS (from ajax)

I use PHP to get it, because I need to download a PDF file from another server. To download this file I need to be logged in and the client shouldn't have to log in there.
The problem is that the PDF file the user gets is just a white page.
On my server there is still content inside when i write it in a file (file_put_contents("test.pdf",$content);)
I tried to base64 encode it before I send it and recognized that the delivered data is still correct. So it fails at the decoding (atob(data)) or in the download function.
(I also tried utf8 encodings)
In the downloaded pdf file, many characters are exchanged with these boxes or question marks(��).
$result = curl_exec($ch);
file_put_contents("test.pdf",$result); //test.pdf contains correct document
echo base64_encode($result);
download(atob(data),"My.pdf") //data is answer of ajax request
function download(data, filename, type) {
var file = new Blob([data], {
type: type
});
if (window.navigator.msSaveOrOpenBlob) // IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function () {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
The problem is the implicit UTF8 encoding in the BLOB constructor.
More information here.
To display a pdf (or any other file type), you will have to set the content type and so on in response header for the browser to resolve it correctly and display. This is a small portion of a code I wrote for delivering pdf content to the user.
$file = '/home/public_html/DriveMode/DRIVES/java.pdf'; //path to file
$filename = 'filename.pdf';
header('Content-type: application/pdf'); //setting content type in header
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
readfile($file); // reads and writes the file to output buffer
Hope this helps you and do let me know in comments if something is confusing here.

filesize is changing during download

i have a pdf file that if downloaded through the viewer it downloads at the correct file size but when i use this code for say download selected the file size of the pdf changes and renders it useless when you open with adobe/nitro/etc.
<?php
#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 'Off');
if (isset($_GET['url'])) {
$fullPath = $_GET['url'];
if($fullPath) {
#$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-Disposition: attachment;
filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
header("Content-type: application/pdf"); // add here more headers for diff. extensions
break;
default;
header("Location: ".$fullPath);
exit;
}
if($fsize) {//checking if file size exist
header("Content-length: $fsize");
}
fopen($fsize, "r");
exit;
}
}
?>
i noticed the file size is 24kb on the server. i go to url and view it then click the download from pdf viewer the file downloads just fine and verified the filesize in my download folder at 24kb. however when i use this code above as my download.php it downloads but comes back as 2kb.
can someone help me figure out why its changing the file size please?
I don't see any code where you are actually sending the file.Make sure you actually send the file. You have used fopen() but you are not using fread() that's why files is getting opened but not getting being read may be that's why it's showing some default output which amounts to 2kb . You can use the much simpler readfile() instead
For that replace this line
fopen($fsize, "r");
with this one
readfile('path/to/' . $path_parts["basename"]);
Just in case you are handling huge files like several MBs then fopen will suite you better as it would be more memory efficient.Also note the b flag in fopen() parameter it refers to binary mode so whenever you are sending a binary file like pdf,images etc you should always use this flag
set_time_limit(0);
$file = #fopen('path/to/' . $path_parts["basename"],"rb");
while(!feof('path/to/' . $path_parts["basename"]))
{
print(#fread('path/to/' . $path_parts["basename"], 1024*2));
ob_flush();
flush();
}
the problem was the / in the url it was starting with. once i added a trim to the url it worked. tbh now that i started looking into this i dont think it really ever work just appeared it did.
$trmfullPath = $_GET['url'];
$fullPath = trim($trmfullPath, "/");
this seemed to fix it. also dont get any errors in my php error log now.

How to download pdf in javascript using soap webservices?

I have a list of bills in my table and each row has it's own unique bill (different date, amount etc...). I have successfully managed to make php call via Soap:Wrapper in Laravel 5 and when i type in browser "path to that procedure" i get my pdf. But i would like to open it using Javascript.
My code of server side
$pdfData= $soap->racun($data);
header("Content-type: application/pdf");
header("Content-Length:" . strlen($pdfData));
//this line if i want to preview my pdf in browser
header("Content-Disposition: inline; filename=pdf.pdf");
//this line if i want to download my pdf
header('Content-Disposition: attachment; filename="pdf.pdf"');
print $pdfData;
My code of client side is
$.ajax({
type:"GET",
url:"/path",
data:"param1=" + par1+"&param2="+ par2+ "&param3="+par3,
success:function(msg){
//alert(msg);
//here needs to show that pdf but don't know how
document.write(msg);
},
fail:function(){
alert('Error with pdf');
}
});
So when a user click on a link to get his bill i send AJAX call and get that pdf using SOAP WebService. The problem is that i can preview it or download it if i write /path in my browser, but don't know how to do it inside Javascript. What am i doing wrong?
Well, you're sending a GET request, so you can simply do this:
window.location = "/path?" + "param1=" + par1+ "&param2=" + par2 + "&param3=" + par3;
You might also want to check this answer.

downloading image in code format

i m trying to make a button that downloads the image and what i did is, made a function like this:
function download_image(){
$file = $_POST['file'];
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");//notice this content-type, it will force a download since browsers think that's what they should do with .exe files
header("Content-disposition: attachment; filename= ".$file."");
readfile($file);
}
and when download button is clicked i performed this js:
$.ajax({
type:"POST",
url:'..address to../download_image',
data:{
file:imgElem
},
success:function(){
alert('image downloaded');
}
});
Now the problem is i don't have image name but is coded image like this:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABBgAAAEtCAYAAACibtPQAAAgAElEQVR4nO3dX28c150mYH+c+S57s5d7uVcFGMEGuQiwgW+ycCEAsdl4gQjGJqsyYIyCYEbwEDXKZD1KNLHVtjMZDeM/kmmWLJmOrSiOzViOJDJiHNtnLoLqLRarm8VDFfsU63mBBzabzWZ12/rp1MtTzSdCCKEoipBlWciyLFRVFbpSVdX8PlmWhTzPO+8nIiIiIiIiItPLE7PZLJRlGUIIoSzLUBRF5x3rgkFEREREREREpJ0nmh8oGEREREREREQkJvOCIc/z+U6GrrQvkVh2XxERERERERGZVo61g6H+nN0MIiIiIiIiItLME+0b+hYHy94QUkRERERERESmlSfKsgyz2SyEEMJsNjvw2yHyPO/c0WAHg4iIiIiIiIg080QIi39NZbNgaL8HQ11KiIiIiIiIiIgcukRCREREREREROS4UTCIiIiI...PHWSgveiOXekFY/8Rr2ZBZ9hO1+vu2t8Mt+7r2Frr2X0JH3Z7n+aECob3Ntvn1zeNoP+/2cXY9FwWDSNqZwtzsWqDX861rV8NRBUP99V3zc9G8zfN8/vXtOdr1NUct1tvPXUTis2iXQAiH3xCwvTOrOQOan2+v15pf03WSuuj71DOjXYC014Lt+3Z97xC6d2097ufSTvuyjeZusaMe9yQFQ/Pxu55L83gf5/OVdKNgkDORRdvRRESkO6c1N+tLMeos2sorIiIi44+CQUadrsZZREQW57TnZv0TKDsCREREzn4UDCIiIiIiIiJy4igYREREREREROTEUTCIiIiIiIiIyImjYBARERERERGRE0fBICIiIiIiIiInjoJBRERERERERE4cBYOIiIiIiIiInDgKBhERERERERE5cRQMIiIiIiIiInLiKBhERERERERE5MRRMIiIiIiIiIjIiaNgEBEREREREZET5z8AyGKspBK3ENIAAAAASUVORK5CYII=">
so the problem is how should i download the image??? Please help:(
Just set the window.location to the encoded URI, eg
window.location.href = 'data:image/png;base64,iVBORw0KGgo...
or you can also open a popup window
http://jsfiddle.net/vaibviad/VE8Qn
If you want to have file name and extension then you can also try this
<a download="FILENAME.EXT" href="data:image/png;base64,asdasd...">Download</a>
Below link is demo with download attribute with filename and ext
http://jsfiddle.net/vaibviad/VE8Qn/3/
NOTE: Download attribute is not widely supported
JavaScript cannot save a file, so in this situation you need to return a url from your API then in your success function you'll use the window.location = ....returned value... this will download the file.
If a DEMO is needed please let me know.

Categories