Acceptă apelul AJAX cu date de formular serializate
Î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.
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.

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.

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.
