Acceptă apelul AJAX cu date de formular serializate

20 oct. 2013, 01:42:21
Vizualizări: 23.9K
Voturi: 1

Încerc să transmit unor date de formular către un plugin WordPress prin AJAX și funcționează bine, cu excepția cazului când datele formularului sunt serializate - atunci serverul răspunde cu un mesaj de eroare. Mă chinui cu asta de câteva zile și nu reușesc să o fac să funcționeze. Ce fac greșit? Nu poate fi atât de greu, nu?

Iată mesajul de eroare:

call_user_func_array() așteaptă ca parametrul 1 să fie un callback valid, funcția 'process_request' nu a fost găsită sau numele funcției este invalid în X:\xampp\htdocs\testsite\wp-includes\plugin.php la linia 406

Apelul AJAX:

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

nonce: whatever 

//dacă folosesc această variabilă, funcționează bine
var data = {action: 'process_request', add_my_data: 'whatever', 'my_data[name]':'whatever', my_nonce: nonce};

//dacă folosesc această variabilă, serverul returnează eroarea de mai sus
//deoarece .serialize() nu include numele butonului submit
//și formularul nu conține numele funcției care trebuie apelată, le-am adăugat manual în string. nonce este preluat din formular.

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 (funcționează) sau data2 (nu funcționează),
[...]

Ciudat este că datele post pentru 'data2' par să fie ok și au aceeași sintaxă ca pentru 'data'.

Am verificat datele post cu firebug:

pentru 'data':

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

pentru 'data2' (cu formularul serializat, singura diferență pe care o văd este referrer-ul):

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

Funcția PHP care gestionează cererea:

function process_request() {

    //validarea nonce omisă pentru lizibilitate

    if( isset ($_POST['add_my_data']) ) {
        $this->add_info_array('placeholder', 'Baza de date actualizată');
    }
            //fă niște lucruri aici
            die();
        }
      add_action('wp_ajax_process_request', 'process_request');

UPDATE: Problema este referrer-ul din string-ul care este creat pentru 'data2'. Verificați comentariul meu de mai jos.

6
Comentarii

Trebuie să arăți puțin mai mult cod, unde e hook-ul?

brasofilo brasofilo
20 oct. 2013 02:13:17

e acolo, doar că nu l-am inclus mai sus (l-am inclus acum). cum am spus, funcția și apelul ajax funcționează, doar că nu merge cu datele post serializate

JimQ JimQ
20 oct. 2013 02:26:11

Mesajul de eroare spune că process_request() nu este definită. De unde vine această funcție?

kaiser kaiser
20 oct. 2013 02:51:10

Această funcție se află în fișierul meu de plugin.

JimQ JimQ
20 oct. 2013 03:05:25

Bine, referer-ul din șirul care este creat pentru 'data2' pare a fi problema. Dacă înlocuiesc partea serializată() cu șirul pe care l-am obținut din Firebug și elimin referer-ul, dintr-o dată funcționează. Dacă îl las acolo, aceeași problemă ca mai înainte. Deci noua întrebare este: De ce referer-ul din șir face ca WordPress să arunce acel mesaj de eroare și cum pot preveni includerea lui cu serialize()? Nu face nici măcar parte din formular, deci de unde vine?

JimQ JimQ
20 oct. 2013 15:53:47

OK, ne apropiem tot mai mult: Am folosit wp_nonce_field în formular, asta face ca WordPress să creeze un câmp ascuns cu referer-ul în el, deci asta explică de unde vine. Ultima întrebare rămasă: De ce referer-ul cauzează o problemă?

JimQ JimQ
20 oct. 2013 16:04:07
Arată celelalte 1 comentarii
Toate răspunsurile la întrebare 2
0

Când lucrez cu AJAX și Formulare în WordPress, prefer să codific acțiunea AJAX direct în formular, astfel încât funcția serialize() să funcționeze fără probleme. De fapt, am scris un articol despre asta anul trecut: https://webdevstudios.com/2015/02/12/handling-ajax-in-wordpress/

Dar, sunteți aici pentru răspunsuri, nu pentru un articol de blog, așa că iată partea scurtă. Aveți trei componente aici: primul este formularul HTML. Puteți profita de serialize() prin includerea acțiunii într-un câmp ascuns al formularului. Iată un exemplu:

<form class="my_form">
    <?php wp_nonce_field( 'my_action_nonce' ); ?>
    <input type="hidden" name="action" value="my_action" />
    <!-- Mai multe câmpuri aici... -->
    <input type="submit" name="submit" value="Trimite" class="submit_form_btn" />
</form>

Observați câmpul ascuns numit action. Desigur, am păstrat wp_nonce_field() din motive de securitate.

A doua parte este jQuery-ul. După cum am menționat anterior, nu este necesar să accesați AJAX prin obiectul jQuery original, deoarece l-ați transmis deja ca $, dar nu strică nimic, doar că nu este o practică bună.

jQuery( document ).ready( function( $ ) {
    $( '.submit_form_btn' ).on( 'click', function( evt ) {
        // Opriți trimiterea implicită a formularului
        evt.preventDefault();
        // Serializați întregul formular, care include acțiunea
        var serialized = $( '.my_form' ).serialize();
        $.ajax( {
            url: ajaxurl, // Această variabilă este definită undeva
            method: 'POST',
            data: serialized, // Aici sunt datele noastre serializate
        } ).done( function( result ){
            // Gestionați rezultatul aici...
        } );
    } );
} );

Am încercat să comentez codul cât mai bine posibil, ar trebui să aibă mai mult sens, dar permiteți-mi să explic. Mai întâi opriți trimiterea formularului folosind metoda preventDefault() a obiectului evt (prescurtare de la event).

Apoi serializați datele formularului și le stocați într-o variabilă. Presupun că ați putea să o scurtați și să o introduceți direct în obiectul data, dar asta depinde de voi.

Partea finală, ei bine, trebuie să vedeți ce trimiteți, nu? Aici vin la îndemână error_log și print_r. Iată cum:

<?php

function handle_ajax() {
    // Aici verificați nonce-ul
    if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'my_action_nonce' ) ) {
        // Puteți fie să returnați, fie să folosiți funcții JSON elegante
        wp_send_json_error();
    }
    // Aici ar trebui să obțineți TOATE datele dvs. într-o variabilă $_POST
    // sau puteți face ceva de genul acesta și apoi să verificați jurnalul de erori

    error_log( print_r( $_POST, 1 ) );

    // Aceasta va afișa ÎNTREAGA variabilă $_POST în debug.log dacă o aveți
    // activată, dacă nu, merge în jurnalul de erori PHP

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

Acum, acest cod AR TREBUI să vă gestioneze cererile AJAX. Ce faceți cu datele depinde de voi.

11 ian. 2016 06:56:34
3

De ce folosești jQuery.ajax?

Când definești jQuery(document).ready(function($) {... $ devine variabila ta globală jQuery. WordPress jQuery noConflict Wrapper

Apelul tău ajax ar trebui să arate astfel:

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

Apoi, nu poți să transmiți doar un șir de variabile. Trebuie mai întâi să le definesc într-un obiect, și să-l transmiți pe acela.

Încearcă asta:

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

Nu sunt sigur despre serializare totuși... cred că WordPress deja face asta în timpul procesării cererii ajax. Poate ar trebui să cercetezi mai mult pe acest subiect.

20 oct. 2013 02:45:38
Comentarii

Aveți dreptate în legătură cu variabila jQuery, dar nu a schimbat nimic, așa cum am spus, dacă nu este serializat, totul funcționează perfect.

JimQ JimQ
20 oct. 2013 03:14:45

scuze, acesta a fost primul comentariu, nu l-am mai putut edita:

JimQ JimQ
20 oct. 2013 03:21:03

Mulțumesc pentru sugestie, dar dacă fac asta, datele serializate() vor fi definite ca valoare a add_my_data. Astfel: add_my_data:action=process_request&add_my_data=orice&...

JimQ JimQ
20 oct. 2013 03:21:26