it-swarm.com.de

Akzeptieren AJAX Aufruf mit serialisierten Formulardaten

Ich versuche, ein WordPress-Plugin mit einigen Formulardaten über Ajax zu senden. Wenn die Formulardaten nicht serialisiert sind, funktioniert das einwandfrei. Der Server antwortet dann mit einer Fehlermeldung. Ich bin schon seit Tagen damit festgefahren, aber ich kann es nicht zum Laufen bringen. Was mache ich falsch, das kann doch nicht so schwer sein, oder?

Hier ist die Fehlermeldung:

call_user_func_array () erwartet, dass Parameter 1 ein gültiger Rückruf, die Funktion 'process_request' nicht gefunden oder ein ungültiger Funktionsname in X:\xampp\htdocs\testsite\wp-includes\plugin.php in Zeile 406 ist

Der AJAX Aufruf:

jQuery(document).ready(function($) {

nonce: whatever

//if i use this variable, it works fine 
var data = {action: 'process_request', add_my_data: 'whatever', 'my_data[name]':'whatever', my_nonce: nonce};

//if i use this variable, the server returns the above error .
//because .serialize() doesn't include the submit button's name
//and the form doesn't contain the name of the function to be called, i added them manually to the string. nonce is pulled from form.

var data2 ='action=process_request&add_my_data=whatever&' + $('#my-form').serialize();


$('.my_submit_button').click(function(event) {       
event.preventDefault(); 

jQuery.ajax({
type : 'post',
url : ajaxurl,
timeout: 25000,
data : //data (works) or data2 (doesn't work),
[...]

Das Seltsame ist, dass die Post-Daten für 'data2' in Ordnung zu sein scheinen und die gleiche Syntax wie für 'data' haben.

Ich habe die Post-Daten mit Firebug kontrolliert:

für 'Daten':

action=process_request&add_my_data=whatever&my_data%5Bname%5D=whatever&my_nonce=1b444dd703 

für 'data2' (mit dem Formular serialisiert, der einzige Unterschied, den ich sehe, ist der Referer):

action=process_request&add_my_data=whatever&my_data%5Bname%5D=whatever&my_nonce=1b444dd703&_wp_http_referer=%2Ftestsite%2Fadmin%2Ftestpage%2F

Die PHP -Funktion, die die Anfrage bearbeitet:

function process_request() {

    //nonce validation left out for readability

    if( isset ($_POST['add_my_data']) ) {
        $this->add_info_array('placeholder', 'Database updated');
    }
            //do some stuff here
            die();
        }
      add_action('wp_ajax_process_request', 'process_request');

UPDATE: Das Problem ist der Verweis in der Zeichenfolge, die für 'data2' erstellt wird. Überprüfen Sie meinen Kommentar unten.

1
JimQ

Wenn ich mit AJAX und Formularen in WordPress arbeite, codiere ich gerne die Ajax-Aktion in das Formular, damit die Serialisierung sofort funktioniert. Eigentlich habe ich letztes Jahr einen Artikel darüber geschrieben: https://webdevstudios.com/2015/02/12/handling-ajax-in-wordpress/

Aber Sie sind hier, um Antworten zu erhalten, kein Blog-Artikel. Hier ist der kurze Teil davon. Sie haben hier drei Teile, erstens das HTML-Formular. Sie können serialize() nutzen, indem Sie die Aktion in ein verborgenes Formularfeld einfügen. Hier ein Beispiel:

<form class="my_form">
    <?php wp_nonce_field( 'my_action_nonce' ); ?>
    <input type="hidden" name="action" value="my_action" />
    <!-- More fields here... -->
    <input type="submit" name="submit" value="Submit" class="submit_form_btn" />
</form>

Beachten Sie das ausgeblendete Formularfeld mit dem Namen action. Natürlich habe ich die wp_nonce_field() behalten, da nun Sicherheitsfragen.

Der zweite Teil ist die eigentliche jQuery, wie bereits erwähnt, Sie müssen nicht über das ursprüngliche jQuery-Objekt auf AJAX zugreifen, da Sie es bereits als $ übergeben haben, aber es schadet eigentlich nichts schlechte Praxis.

jQuery( document ).ready( function( $ ) {
    $( '.submit_form_btn' ).on( 'click', function( evt ) {
        // Stop default form submission
        evt.preventDefault();
        // Serialize the entire form, which includes the action
        var serialized = $( '.my_form' ).serialize();
        $.ajax( {
            url: ajaxurl, // This variable somewhere
            method: 'POST',
            data: serialized, // This is where our serialized data is
        } ).done( function( result ){
            // Handle the result here...
        } );
    } );
} );

Ich habe versucht, den Code so gut wie möglich zu kommentieren. Er sollte sinnvoller sein, aber lassen Sie mich das erklären. Zuerst stoppen Sie die Formularübermittlung mit der Methode preventDefault() des Objekts evt (kurz für event).

Anschließend serialisieren Sie die Formulardaten und speichern sie in einer Variablen. Ich nehme an, Sie könnten es verkürzen und einfach in das Datenobjekt ablegen, aber das liegt bei Ihnen.

Der letzte Teil, nun, müssen Sie sehen, was Sie richtig posten? Hier kommen error_log und print_r zum Einsatz:

<?php

function handle_ajax() {
    // Here you verify your nonce
    if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'my_action_nonce' ) ) {
        // You can either return, or use nifty json stuffs
        wp_send_json_error();
    }
    // Here you should get ALL your data in a $_POST variable
    // or you can actually do someting like this then check your error log

    error_log( print_r( $_POST, 1 ) );

    // This will print out the ENTIRE $_POST variable to your debug.log if you have it
    // enabled, if not, it goes to your PHP error log

}
add_action( 'wp_ajax_my_action', 'handle_ajax' );

Nun, da Sie Ihre Ajax für sich selbst behandeln SOLLTEN, liegt es an Ihnen, was Sie mit den Daten tun.

2
Jay Wood

Warum benutzt du jQuery.ajax?

Wenn Sie jQuery(document).ready(function($) {... $ definieren, wird dies Ihre globale jquery-Variable. WordPress jQuery noConflict Wrapper

Dein Ajax sollte ungefähr so ​​aussehen:

$.ajax({
type : 'post',
url : ajaxurl,
etc : ....

Als Nächstes können Sie nicht einfach eine Zeichenfolge von Variablen übergeben. Sie müssen sie zuerst in ein Objekt definieren und das übergeben.

Versuche dies:

get_data = $('#my-form').serialize();
var data = {action: 'process_request', add_my_data: get_data, my_nonce: nonce};

Ich bin mir jedoch nicht sicher, ob die Serialisierung funktioniert. Ich dachte, WordPress hat dies bereits während des Ajax-Postprozesses getan. Möglicherweise müssen Sie dort weitere Nachforschungen anstellen.

0
josh