Metodo corretto per passare variabili di query in AJAX usando ajaxurl
OK, non sapevo come intitolare questo argomento.
Sto cercando di sovrascrivere il comportamento predefinito con AJAX. Il problema qui non è realmente un problema, ma più un desiderio.
Ho questo URL:
<a href="http://example.com/?reaction=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Rimuovi post</a>
Nel file functions.php
ho questa funzione e la chiamata subito dopo:
function smk_remove_post(){
if( !empty( $_GET['reaction'] ) && 'smk_remove_post' == $_GET['reaction'] && !empty( $_GET['id'] ) ){
if( current_user_can('edit_others_posts') && !empty($_GET['_nonce']) ){
if( wp_verify_nonce( esc_html( $_GET['_nonce'] ), 'smk_remove_post' ) ){
// Elimina il post
wp_delete_post( absint( $_GET['id'] ), true );
}
}
}
}
smk_remove_post();
Ora se clicco sul link il post con ID 1226
verrà rimosso. Tutto funziona. Il compito viene eseguito con successo e la pagina viene ricaricata.
È qui che ho bisogno di AJAX. Voglio elaborare questo URL usando ajax senza ricaricare la pagina, e ottenere una risposta appropriata.
Ho aggiunto questo script jQuery:
function smk_remove_post(){
$('.smk-remove-post').on( 'click', function( event ){
event.preventDefault();
var _this = $(this);
jQuery.ajax({
type: "GET",
url: _this.attr('href'),
success: function(response){
console.log(response);
_this.text('Tutto ok, il post è stato rimosso.');
}
});
});
}
smk_remove_post();
Tutto funziona come previsto. Il post viene rimosso via ajax e non c'è bisogno di ricaricare la pagina. Ma non riesco a ottenere una risposta appropriata, invece ottengo l'intero codice HTML della pagina corrente.
So che dovrei usare admin-ajax.php
(ajaxurl), ma come faccio? Devo inviare la query dall'URL e ottenere la risposta indietro.
Ecco cosa ho provato:
Ho aggiunto questo allo script jQuery sopra:
data: {
'action': 'smk_remove_post_ajax',
},
E questo al PHP:
function smk_remove_post_ajax(){
smk_remove_post();
die();
}
add_action('wp_ajax_smk_remove_post_ajax', 'smk_remove_post_ajax');
Non funziona. Viene ignorato, viene eseguita la chiamata precedente invece, come se fosse fatto senza ajax.
Capisco che devo in qualche modo inviare la query a admin-ajax.php, ma come?
Finalmente ci sono riuscito.
Il primo errore era quello di elaborare la stessa funzione due volte. L'avevo chiamata una volta dopo la funzione e un'altra nell'azione ajax. Quindi quando usavo la chiamata ajax, la funzione veniva eseguita due volte. Nell'esempio dell'OP, questo non è affatto un problema, perché è semplificato per fare solo una cosa, ma nel mio codice reale fa molto di più e può comportare la perdita di dati indesiderati.
Inoltre, avevo solo bisogno di fermare l'ajax e ottenere una risposta personalizzata, nient'altro. Ecco cosa ho fatto:
1. Ho cambiato questo:
smk_remove_post();
in questo:
add_action('parse_query', 'smk_remove_post');
È meglio eseguire la funzione più tardi quando è necessaria in un'azione speciale.
2. Poi ho modificato il gestore ajax:
Ho eliminato questa riga smk_remove_post();
e cambiato l'azione ajax da wp_ajax_smk_remove_post_ajax
a wp_ajax_smk_remove_post
:
function smk_remove_post_ajax(){
wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');
3. Ho rinominato la stringa di query reaction
in action
. L'ho cambiato nell'URL e nella funzione:
4. Infine ho modificato lo script jQuery. In modo che usi admin-ajax.php e invii l'URL come dati:
url: ajaxurl,
data: _this.attr('href'),
Ecco il codice finale:
Link:
<a href="http://example.com/?action=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Rimuovi post</a>
Codice PHP:
function smk_remove_post(){
if( !empty( $_GET['action'] ) && 'smk_remove_post' == $_GET['action'] && !empty( $_GET['id'] ) ){
if( current_user_can('edit_others_posts') && !empty($_GET['_nonce']) ){
if( wp_verify_nonce( esc_html( $_GET['_nonce'] ), 'smk_remove_post' ) ){
// Elimina il post
wp_delete_post( absint( $_GET['id'] ), true );
}
}
}
}
add_action('parse_query', 'smk_remove_post');
function smk_remove_post_ajax(){
wp_die( 'ok' );
}
add_action('wp_ajax_smk_remove_post', 'smk_remove_post_ajax');
Javascript:
function smk_remove_post(){
$('.smk-remove-post').on( 'click', function( event ){
event.preventDefault();
var _this = $(this);
jQuery.ajax({
type: "GET",
url: ajaxurl,
data: _this.attr('href').split('?')[1],
success: function(response){
console.log(response); // ok
_this.text('Tutto a posto, il post è stato rimosso.');
}
});
});
}
smk_remove_post();
Modifica:
Anche un piccolo aggiornamento al codice sopra. Per elaborare le stringhe di query è necessario eliminare il percorso del sito, altrimenti potrebbe creare problemi imprevisti. Ho aggiunto questo a data href
:
.split('?')[1]

Crea un link in questo modo
<a href="http://example.com/?reaction=smk_remove_post&id=1226&_nonce=7be82cd4a0" data-id="1226" data-nonce="7be82cd4a0" class="smk-remove-post">Rimuovi post</a>
E jQuery
$('.smk-remove-post').on( 'click', function( event ){
event.preventDefault();
var _this = $(this);
var data = {
'action': 'smk_remove_post_ajax',
'reaction': 'smk_remove_post',
'id': _this.data('id'),
'_nonce': _this.data('nonce')
};
// a partire dalla versione 2.8 ajaxurl è sempre definito nell'header di amministrazione e punta a admin-ajax.php
jQuery.ajax({
type: "GET",
url: ajaxurl,
data: data,
success: function(response){
console.log(response);
_this.text('Tutto ok, il post è stato rimosso.');
}
});
});
Consulta il Codex riguardo AJAX nei Plugin. E nel Codex, dice:
La maggior parte delle volte dovresti usare wp_die() nella tua funzione di callback AJAX. Questo fornisce una migliore integrazione con WordPress e rende più semplice testare il tuo codice.
Quindi usa wp_die();
invece di die();

Questo è quello che ho usato in precedenza, ma qui ho bisogno che il codice funzioni con o senza ajax.

Se disabilito il javascript, passerà al ricaricamento della pagina ed elaborerà l'azione senza ajax. Nel tuo esempio funzionerà solo se JS è abilitato.

AJAX non è magico e quando si richiede l'URL X si riceverà lo stesso HTML per quell'URL sia che lo si faccia dalla barra degli indirizzi del browser, da un link o via AJAX. Pertanto, se si desidera una risposta diversa dall'HTML, non è possibile utilizzare lo stesso URL per la richiesta AJAX come nel link.
WordPress ha un "endpoint" speciale per gestire le richieste AJAX - admin-ajax.php e tutte le richieste AJAX dovrebbero essere inviate solo a questo, qualcosa come $.ajax({url:....admin-ajax.php})
Successivamente è necessario far sapere a WordPress cosa si vuole fare e per questo c'è un parametro speciale nella richiesta chiamato action
. Questo parametro identificherà l'hook da utilizzare lato server per gestire la richiesta. Questa parte è stata gestita correttamente nel tuo codice.
Ora servono i parametri aggiuntivi che identificano quale oggetto dovrebbe essere manipolato o recuperato dall'operazione AJAX. Si può usare il permalink del post, o l'ID del post ad esempio, ma tutto dipende dalla complessità dell'operazione che si sta tentando di fare. Nel tuo caso specifico immagino che un ID del post sia il parametro migliore da passare nella richiesta.
Come inviare i parametri? La maggior parte delle persone fa una richiesta POST quando esegue AJAX, ma se si desidera una GET allora è possibile passarli come parte dell'URL (cosa che presumo jQuery farà esattamente per te).
