Отправка данных от JavaScript до PHP - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть веб-приложение для подписи pdf-файлов. Я могу загрузить pdf-файл в систему и сохранить его как blob-файл в базе данных mysql. В программе просмотра я могу просмотреть pdf-файл с таким кодом:

<?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>
...

При нажатии на кнопку начинается процесс подписания. Я использую эту библиотеку для подписи: https://github.com/Communication-Systems-Group/pdfsign.js Это код для подписи:

$('#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) должен отправить подписанные PDF-данные на php и php должен сохранить данные обратно в базу данных как blob, чтобы следующий пользователь мог подписать pdf-файл таким же образом. Вот моя проблема, я не могу получить действительные BLOB-данные в php. В JavaScript pdfSigned - это объект, а в PHP - это массив, и у меня нет идей обрабатывать данные и как преобразовать их в BLOB-объекты.

Привет и извините за мой плохой английский sh

ilikefatcats

ОБНОВЛЕНИЕ !!

Код convertDataURIToBinary ():

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);
}

Этот код первоначально взят из библиотеки PDFsign, я не изменяю что-то.

Я пытался реализовать метод sendDataToPHP() по-разному. пример:

подпись. 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();

}

В результате вы получите: $ signature_file = NULL $ pdfdata - это массив с ровно 1000 записей чисел. это выглядит так:

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";} 

Я не знаю, как обращаться с этим массивом .. это мой pdf-файл? как сделать это в BLOB? Я попытался разобрать его в json, но тогда у меня просто есть json файл с числами ...

* edit: я обнаружил, что этот массив включает в себя 1000 чисел от 0 до 255, может быть, это помогает ...

Другой попыткой было написать этот код в подписи. 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);
    });       
}

, но в этой попытке я не могу найти файл upload_system_va.php, файл находится в тот же каталог, что и подпись. js. Может быть, мой URL неверен?

Я отправляю логическое «представление», потому что это запускает мою функцию signatureDoc_to_db () в upload_system_va. php:

if(isset($_POST['view'])) {
    signedDoc_to_db();
}

Третий способ, который я нашел в Интернете нужно было создать файл BLOB-объекта перед его отправкой на 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");
            }
        });
    }
}

, но здесь та же проблема, что и при попытке 2: я не набираю код PHP.

Мои навыки в JS не очень хороши, я никогда раньше не работал с этим языком. Может быть, этот код может помочь, это код из библиотеки pdfsign, чтобы загрузить файл после подписания, и это хорошо работает:

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);
}

Массив в списке параметров - это файл pdfSigned сверху. Может быть, этот код может помочь мне? Я попробовал это:

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");
                }
            }
        );
    }
}

, но затем я получаю следующее сообщение об ошибке в журнале консоли:

TypeError: 'slice' called on an object that does not implement interface Blob.

Я надеюсь, что мой вопрос понятен, и кто-то может помочь мне. Если вам нужна дополнительная информация, пожалуйста, спросите.

Greetz и еще один извините за мой engli sh,

ilikefatcats

...