0

I have written a jQuery function using jsPDF to convert a form to PDF, I have then added an ajax command with the intention of saving the generated PDF to the server. However, when I click submit, the page appears to be completing an action. but, when I look at console I see:

POST website.com/wp-admin/admin-ajax.php 400 (bad request)

and I cannot figure out where my code has went wrong.

I have registered my JS and used wp_localize in functions.php:

function ASAP_scripts() {
wp_register_script('js-pod', get_stylesheet_directory_uri() . '/js/POD.js', array('jquery'),'1.1', true);
wp_enqueue_script('js-pod');
wp_localize_script( 'js-pod', 'jspod',
        array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}

add_action( 'wp_enqueue_scripts', 'ASAP_scripts' );  

I have also added my ajax commands again in functions.php

add_action( 'wp_ajax_my_ajax_request', 'so56917978_upload_callback' );
add_action( 'wp_ajax_nopriv_my_ajax_request', 'so56917978_upload_callback' );
function so56917978_upload_callback() {
    if ( ! empty( $_POST['data'] ) ) {
        $data = base64_decode($_POST['data']);
        file_put_contents( "get_stylesheet_directory_uri() . '/POD/pod.pdf' ", $data );
        echo "success";
    } else {
        echo "No Data Sent";
    }

    die;
}

My jQuery:

function sendToServer() {  
          html2canvas(document.getElementById("product_sheet"), {
            onrendered: function(canvas)
            {
          console.log("#submit clicked");

          var img = canvas.toDataURL("image/png");
          var doc = new jsPDF('p', 'pt', 'a4');
          doc.addImage(img, 'JPEG',20,20);
          var file = doc.output('blob');
          var pdf = new FormData();     // To carry on your data  
          pdf.append('mypdf',file);

          $.ajax({
            url: '/wp-admin/admin-ajax.php',   //here is also a problem, depends on your 
            data: {
              action: 'so56917978_upload', // Action name.
              data: pdf,
            },
            dataType: 'text',
            processData: false,
            contentType: false,
            type: 'POST',
          }).done(function(data){
            console.log(data);
          });
            }
          });
          }

Any help in solving this would be great. I have seen similar questions on here but I feel as though I have covered all the bases which they discuss and genuinely cannot see my issue

Update...

Update...

I have changed MY JS slightly, it seems to work better and more as expected, however, I am still getting `no data sent. So the ajax request seems to be working. but, it appears that there may be something in the PHP which is stopping it from completing?

JS

function sendToServer() { 
            html2canvas(document.getElementById("product_sheet"), {
            onrendered: function(canvas)
            {
          console.log("#pdfsubmit clicked");

                function html() {
                    var img = canvas.toDataURL("image/png");
                    var doc = new jsPDF('p', 'pt', 'a4' );
                    doc.addImage(img, 'JPEG', 20, 20);

                    var pdf = doc.output('blob');
                    $.ajax({
                        url: jspod.ajax_url,
                        type: 'post',
                        async: false,
                        contentType: 'application/json; charset=utf-8',
                        data:{
                            data: pdf
                            action:'so56917978_upload'
                        },
                        dataType: 'json'
                    });
                }
            });
        }
    }

PHP:

add_action( 'wp_ajax_so56917978_upload', 'so56917978_upload' );
add_action( 'wp_ajax_nopriv_so56917978_upload', 'so56917978_upload' );
function so56917978_upload() {
    if ( ! empty( $_POST['action'] ) ) {
        $data = base64_decode($_POST['action']); 
        file_put_contents( get_template_directory() . '/POD/pod.pdf' , $data );
        echo "success";
    } else {
        echo "No Data Sent";
    }

    die();
}
SupGen
  • 195
  • 17

2 Answers2

0

just change you action hooks with the name which you have used in ajax request action: 'so56917978_upload'

add_action( 'wp_ajax_so56917978_upload', 'so56917978_upload' );
add_action( 'wp_ajax_nopriv_so56917978_upload', 'so56917978_upload' );

also it will be good if you use localize variable instead of hard coding the url in ajax url: '/wp-admin/admin-ajax.php' although it has nothing to do with your problem but its good practice.

EDIT -

you also need to append action in FormData and then in ajax you need to pass that pdf object in data object so basically your code will look like this

pdf.append('action', 'so56917978_upload');

$.ajax({
    url: jspod.ajax_url,   //here is also a problem, depends on your 
    data: pdf,
    dataType: 'text',
    processData: false,
    contentType: false,
    type: 'POST',
}).done(function (data) {
    console.log(data);
});

where pdf.append('action', 'so56917978_upload'); will append the action in your FormData object. data: pdf, and this field in ajax will hold you pdf data object.

Akhilesh
  • 927
  • 1
  • 6
  • 21
  • Thank you for your answer, I have tried ammending this but appears to make no difference to the error. I wish Ajax on wordpress was simple lol. I cannot see where else I might be going wrong – SupGen Jul 10 '19 at 08:58
  • can you please share screenshot of what you are seeing in network tab i mean that how data is getting set there. – Akhilesh Jul 10 '19 at 16:39
  • I have added a screenshot to the question – SupGen Jul 10 '19 at 17:07
  • add screenshot of network tab where data is getting sent not console tab. – Akhilesh Jul 10 '19 at 17:09
  • Sorry, New pic added – SupGen Jul 10 '19 at 18:03
  • Sorry, New pics. quite new to this – SupGen Jul 10 '19 at 18:32
  • yes this is the issue `request payload` should not show [object object] instead it should show the data either it is post request or get that's why you are getting error 400. – Akhilesh Jul 10 '19 at 18:37
  • Would that mean there is something wrong with my functions.php call when pulling the data from the JS? – SupGen Jul 10 '19 at 18:40
  • see the edits i made in my answer also regarding your question there is nothing to do with function.php till now as your ajax request is not getting set so we need to fix that first. Once it working then your function.php file will be executed. – Akhilesh Jul 10 '19 at 19:00
  • I am now getting the responce in console - `No data sent` and in network - `Form Data - action: so56917978_upload` – SupGen Jul 10 '19 at 19:24
  • now change this `if ( ! empty( $_POST['data'] ) ) {` to `if ( ! empty( $_POST['mypdf'] ) ) {` as we are now posting mypdf. Change this in function.php file – Akhilesh Jul 10 '19 at 19:30
  • also make sure you are sending mypdf value too https://stackoverflow.com/questions/30918682/how-to-upload-pdf-to-server-from-ajax-data-send-using-jspdf this link can help you with you jspdf code. – Akhilesh Jul 10 '19 at 19:39
  • Still getting - `No Data Sent` I will have a read at that link you sent and see if that can help. Thank you for all your help, you have been great :-) – SupGen Jul 10 '19 at 19:50
  • now only left part is you jspdf code and this link will help that how you can send jspdf data using ajax also you can try decode pdf in base64 and then pass it on. – Akhilesh Jul 10 '19 at 19:53
  • SO when I submit now im still getting no data sent but its telling me that `mypdf: (binary)` – SupGen Jul 10 '19 at 21:54
  • I have 2 x pdf.append() - `pdf.append('mypdf',file);` and `pdf.append('action', 'so56917978_upload');` I am assuming I should change one of them? – SupGen Jul 10 '19 at 22:12
  • I have been studytin that link but from what I can see, if I remove the `mypdf.append('action', 'so56917978_upload');` section it is the same as what I have. I am struggling to figure out how to add the mypdf into the code. does what I ahve above in my updated question look on the right tracks? I need to set mypdf as a variable but unsure about what sort – SupGen Jul 11 '19 at 18:46
  • did you tried this `var pdf = btoa(doc.output()); ` – Akhilesh Jul 12 '19 at 16:44
  • I have changed my JS, it seems to work a bit better than previous but I am still getting the `no data sent` error – SupGen Jul 13 '19 at 19:57
0

You have few errors in the code.

  1. In the JS code, url needs to be jspod.ajax_url. Also, the action needs to be my_ajax_request.

  2. Not sure why you have double quotes in file_put_contents function. Also you might want to use get_template_directory function to get the path rather than URI?

Hope it helps.

Tagr
  • 13
  • 4
  • thanks @Tagr I have tried making these changes but I am getting the same error :-(. I dont know what to do – SupGen Jul 10 '19 at 08:58
  • I have also removed the double quotes from the `file_put_contents` and changed to `get_template_directory` but again, no change – SupGen Jul 10 '19 at 09:23
  • What happens if you comment out these 2 lines? ```$data = base64_decode($_POST['data']);``` and ```file_put_contents( "get_stylesheet_directory_uri() . '/POD/pod.pdf' ", $data );``` – Tagr Jul 10 '19 at 11:30
  • if I comment out those lines I get the same 400 error message – SupGen Jul 10 '19 at 15:07
  • Keep them commented out, and in your JS file comment these lines out ```processData: false,```and ```contentType: false,``` . If still get 400, comment out the ```data: pdf``` too. – Tagr Jul 10 '19 at 16:31
  • when I comment out as mentioned, I get a different error - `Illegal invocation` – SupGen Jul 10 '19 at 17:01