i have a web-application for signing pdf-files. I can upload a pdf-file into the system and store it as blob-file in a mysql database. In the viewer i can view the pdf-file with this code:
<?php
require_once("../controller/upload_system_va.php");
$id = intval($_GET['did']);
$PDF = mysqli_fetch_array(get_fileContent($id));
$PDFdata = $PDF['doc_blob'];
?>
...
<div class="viewer">
<object id="viewer" name="view" data="data:application/pdf;base64,<?php echo $PDFdata ?>" type="application/pdf"></object>
</div>
...
By clicking a button the signing process will start. I use this library for signing: https://github.com/Communication-Systems-Group/pdfsign.js This is the code for signing:
$('#sign_load_btn').click(function () {
var data = document.getElementById("viewer").data;
data = convertDataURIToBinary(data);
pdfSigned = PDFSIGN.signpdf(data, certInput, document.getElementById('password').value);
sendDataToPHP(pdfSigned);
})
sendDataToPHP(pdfSigned)
should send the signed pdf data to php and php should store the data back in the database as blob so that the next user can sign the pdf-file in same way.
Here is my problem, i dont get valid blob-data in php. In JavaScript pdfSigned is an object and in PHP it is an array and i dont have ideas to handle the data and how to convert it to blob.
Greetz and sorry for my bad english
ilikefatcats
UPDATE!!
The code of convertDataURIToBinary() is:
function convertDataURIToBinary(dataURI) {
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = dataURI.substring(base64Index);
return decodeBase64(base64);
}
function decodeBase64(input) {
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var size = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var uint8 = new Uint8Array(input.length);
while (i < input.length) {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
uint8[size++] = (chr1 & 0xff);
if (enc3 !== 64) {
uint8[size++] = (chr2 & 0xff);
}
if (enc4 !== 64) {
uint8[size++] = (chr3 & 0xff);
}
}
return uint8.subarray(0, size);
}
This code is originaly from the library PDFsign i dont change something.
I had tried to implement the sendDataToPHP()
Method in different ways.
example:
signing.js:
function sendDataToPHP(pdfSigned) {
if (pdfSigned != 0) {
alert("insert if: " + pdfSigned);
$.post("viewer.php", {
view: true,
pdfdata: pdfSigned,
},
function (data) {
if (data != "") {
alert("Dateiübergabe erfolgreich");
} else {
alert("Dateiübergabe nicht erfolgreich");
}
}
);
}
}
upload_system_va.php:
function signedDoc_to_db() {
$pdfdata = $_POST['pdfdata'];
$did = 49;
//$signed_file = base64_encode(serialize($pdfdata));
$signed_file = base64_encode($pdfdata);
$dbcon = new PDO("mysql:host=localhost;dbname=signshare", "root", "");
if (!$dbcon) {
die('<p>Fehler beim Verbinden mit der Datenbank!</p>');
}
$insert_signedFile = $dbcon->prepare(
"UPDATE document SET placeholder = :pdfdata WHERE did = :did"
);
$insert_signedFile->bindParam(':pdfdata', $signed_file, PDO::PARAM_LOB);
$insert_signedFile->bindParam(':did', $did);
$insert_signedFile->execute();
}
The result in this way is: $signed_file is NULL $pdfdata is an array with exactly 1000 entries of numbers. its look like:
a:1000{i:0;s:2:"37";i:1;s:2:"80";i:2;s:2:"68";i:3;s:2:"70";i:4;s:2:"45" ... ;i:998;s:3:"153";i:999;s:3:"244";}
I dont know how to handle this array.. is this my pdf-file? how to make it to a blob? I tried to parse it into json but then i just have a json file with numbers...
*edit: i found out that this array includes 1000 numbers from 0 to 255, maybe it helps...
An other attempt was to write this code in signing.js:
function sendDataToPHP3(pdfSigned) {
var fd = new FormData();
fd.append('fname', 'test.pdf');
fd.append('data', pdfSigned);
$.ajax({
type: 'POST',
url: 'upload_system_va.php',
data: fd,
processData: false,
contentType: false,
view: true
}).done(function (data) {
console.log(data);
});
}
but in this attempt I dont reach the file upload_system_va.php
the file is in the same directory like signing.js. Maybe my url is wrong?
I send the boolean 'view' because this start my function 'signedDoc_to_db()' in upload_system_va.php:
if(isset($_POST['view'])) {
signedDoc_to_db();
}
A third way I found in the web was to make a blob file before sending it to PHP:
function sendDataToPHP2(pdfSigned) {
var base64str = encodeBase64(pdfSigned);
var binary = atob(base64str.replace(/\s/g, ''));
var len = binary.length;
var buffer = new ArrayBuffer(len);
var viewA = new Uint8Array(buffer);
for (var i = 0; i < len; i++) {
viewA[i] = binary.charCodeAt(i);
}
var blob = new Blob([viewA], { type: "application/pdf" });
if (pdfSigned != 0) {
alert("insert if: " + blob);
$.ajax({
url: 'http://localhost/mythesis/src/controller/upload_system_va.php',
data: blob,
type: 'POST',
contentType: false,
processData: false,
view: true,
success: function (data) {
alert("Daten wurden verschickt");
}
});
}
}
but here is the same problem like in attempt 2: i dont reach th PHP-code.
My skills in JS are not pretty good, I never worked with this language before. Maybe this code can help, its the code from the pdfsign-library to download the file after signing and this work well:
function createPDFDownload(array, filename) {
var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob([array], { type: 'application/pdf' }));
a.download = filename;
// Append anchor to body.
document.body.appendChild(a);
a.click();
// Remove anchor from body
document.body.removeChild(a);
}
The array in the parameterlist is the pdfSigned file from above. Maybe this code can help me? I tried this one:
function sendDataToPHP(pdfSigned) {
var blob = new Blob([pdfSigned], { type: 'application/pdf' });
if (pdfSigned != 0) {
$.post("viewer.php", {
view: true,
data: blob,
contentType: 'application/pdf',
processData: false
},
function (data) {
if (data != "") {
alert("Dateiübergabe erfolgreich");
} else {
alert("Dateiübergabe nicht erfolgreich");
}
}
);
}
}
but then i get following error-message in the console-log:
TypeError: 'slice' called on an object that does not implement interface Blob.
I hope my question is understanable and someone can helps me. When you need more informations, please ask.
Greetz and another sorry for my english,
ilikefatcats