400 bad request su admin-ajax.php utilizzando solo l'hook d'azione wp_enqueue_scripts
Ho lavorato di recente con ajax. I tutorial che si trovano in rete sono tutti molto simili e abbastanza facili da implementare.
Ma ricevo sempre un bad request 400 sul mio file ajax-admin.php
.
Dopo una lunga e intensiva ricerca, ho scoperto che è dovuto al momento dell'integrazione.
Se uso l'hook d'azione init
per inizializzare lo script e wp_localize_script
, tutto funziona correttamente. Quindi il codice in sé deve essere corretto.
my-page-test-functions.php
function ajax_login_init(){
wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
wp_enqueue_script('ajax-login-script');
wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'URL_REINDIRIZZAMENTO_QUI','loadingmessage' => __('Invio informazioni utente in corso, attendere prego...')));
add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
}
if(!is_user_logged_in()){
add_action('init','ajax_login_init');
}
function ajax_login(){
// il campo nonce viene creato nella pagina
check_ajax_referer('ajax-login-nonce','security');
//CODICE
die();
}
Ma se uso per esempio l'hook d'azione wp_enqueue_scripts
ricevo sempre il bad request.
if(!is_user_logged_in()){
add_action('wp_enqueue_scripts','ajax_login_init');
}
Il problema con questo è:
Vorrei avere le funzioni in un file php separato e caricarle solo se sono necessarie in una particolare pagina. Per questo ho bisogno, per esempio, di is_page()
.
Ma is_page()
funziona al più presto quando aggancio la funzione con l'include nell'hook d'azione parse_query
:
functions.php
function sw18_page_specific_functions(){
if(is_page('page-test')){
include_once dirname(__FILE__).'/includes/my-page-test-functions.php';
}
}
add_action('parse_query','sw18_page_specific_functions');
Quindi le funzioni agganciate all'hook init
nel file my-page-test-functions.php
non vengono attivate, suppongo, perché init
viene prima di parse_query
.
Esistono delle best practice per organizzare questo, in modo che funzioni? O come posso risolvere il bad request di admin-ajax.php
quando uso l'hook d'azione wp_enqueue_scripts
?
Penso che l'unica cosa mancante qui sia che devi spostare add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
al di fuori di ajax_login_init
.
Quel codice registra il tuo gestore Ajax, ma quando lo esegui solo su wp_enqueue_scripts
, è già troppo tardi e gli hook wp_ajax_nopriv_
sono già stati eseguiti.
Quindi, hai provato qualcosa del genere:
function ajax_login_init(){
if ( ! is_user_logged_in() || ! is_page( 'page-test' ) ) {
return;
}
wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
wp_enqueue_script('ajax-login-script');
wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'REDIRECT_URL_HERE','loadingmessage' => __('Invio informazioni utente, attendi...')));
}
add_action( 'wp_enqueue_scripts','ajax_login_init' );
add_action( 'wp_ajax_nopriv_ajaxlogin','ajax_login' );
function ajax_login(){
//il campo nonce è creato nella pagina
check_ajax_referer('ajax-login-nonce','security');
//CODICE
die();
}
Modifica:
Ora è più chiaro che vuoi caricare JavaScript solo su quella pagina specifica. Questo significa che devi inserire il tuo is_page()
dentro ajax_login_init()
. Ho aggiornato il codice di conseguenza.
Ora, perché la tua soluzione non ha funzionato?
Il controllo is_page()
significava che il tuo file di funzioni veniva caricato solo su quella pagina specifica. ajax_login_init()
viene chiamato e i tuoi script vengono accodati. Fin qui tutto bene.
Ora il tuo script effettua la chiamata ajax. Come menzionato nei commenti, le chiamate ajax non sono a conoscenza della pagina corrente in cui ti trovi. C'è un motivo per cui il file si trova in wp-admin/admin-ajax.php
. Non c'è WP_Query
e quindi is_page()
non funziona durante una richiesta ajax.
Dato che non funziona, sw18_page_specific_functions()
non farà nulla in un contesto ajax. Questo significa che il tuo file di funzioni non viene caricato e il tuo gestore ajax non esiste.
Ecco perché devi sempre includere quel file di funzioni e spostare il controllo is_page()
dentro ajax_login_init()
.
Quindi invece di sw18_page_specific_functions() { … }
esegui direttamente include_once dirname(__FILE__).'/includes/my-page-test-functions.php';
. Senza alcuna chiamata add_action( 'parse_query' )
.

Buon suggerimento. Ho cambiato quello (ma lo stesso errore rimane), ma il problema è ancora che il file contenente le funzioni verrà caricato troppo tardi. Ma ho bisogno di un modo per distinguere quale pagina viene utilizzata. - attualmente sto provando a farlo con is_page() come descritto sopra.

Stai cercando di eseguire is_page()
all'interno di ajax_login()
o all'interno di ajax_login_init()
. Il primo non può funzionare perché è in un contesto Ajax.

Ho enumerato i file in cui si trovano le funzioni, come testo descrittivo sopra. La is_page() viene utilizzata nel functions.php e serve per includere il file con le funzioni ajax solo quando necessario.

Se qualcuno sta utilizzando un approccio basato su classi e riscontra un problema AJAX 400, potrebbe essere necessario spostare i gestori AJAX fuori dalla classe (prova nel file principale del plugin) e utilizzare la classe e il metodo come secondo argomento.
add_action( 'wp_ajax_your_handle', [ 'Class_Name', 'function_name' ] );
add_action( 'wp_ajax_nopriv_your_handle', [ 'Class_Name', 'function_name' ] );

Ciao Zee Xhan. Benvenuto nel sito. La tua risposta necessita di alcune revisioni. Innanzitutto, se la tua risposta contiene codice, non pubblicare uno screenshot. Invece, pubblica il codice come snippet e formattalo come codice (usa il pulsante {}). Questo è probabilmente il motivo per cui la tua risposta è stata votata negativamente e non accettata. Inoltre, una spiegazione più dettagliata sarebbe utile - ad esempio il "perché" usare semplicemente die(), e dove esattamente va inserito in relazione al codice nell'OP (post originale)?
