Metoda corectă de a transmite variabile de interogare în AJAX folosind ajaxurl

31 mar. 2015, 16:31:34
Vizualizări: 16.3K
Voturi: 5

OK, nu am știut cum să denumesc acest subiect.

Încerc să suprascriu comportamentul implicit cu ajax. Problema aici nu este de fapt o problemă, ci mai degrabă o dorință.

Am acest URL:

<a href="http://example.com/?reaction=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Șterge postarea</a>

În fișierul functions.php am această funcție și apelul imediat după:

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' ) ){
                // Șterge postarea
                wp_delete_post( absint( $_GET['id'] ), true );
            }
        }
    }
}
smk_remove_post();

Acum, dacă dau click pe link, postarea cu ID-ul 1226 va fi ștearsă. Totul funcționează corect. Sarcina este îndeplinită cu succes și pagina se reîncarcă.

Aici intervine nevoia de AJAX. Vreau să procesez acest URL folosind ajax fără să reîncarc pagina, și să primesc un răspuns adecvat.

Am adăugat acest 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('Totul e în regulă, postarea a fost ștearsă.');
            }
        });
    });
}
smk_remove_post();

Totul funcționează conform așteptărilor. Postarea este ștearsă prin ajax și nu este nevoie să reîncarc pagina. Dar nu pot obține un răspuns adecvat, în schimb primesc întregul cod HTML al paginii curente.

Știu că ar trebui să folosesc admin-ajax.php(ajaxurl), dar cum o fac? Trebuie să trimit interogarea din URL și să primesc răspunsul înapoi.

Iată ce am încercat:

Am adăugat acest cod la scriptul jQuery de mai sus:

data: {
    'action': 'smk_remove_post_ajax',
},

Și acest cod la PHP:

function smk_remove_post_ajax(){
    smk_remove_post();
    die();
}
add_action('wp_ajax_smk_remove_post_ajax', 'smk_remove_post_ajax');

Nu funcționează. Este ignorat, apelul anterior este executat în schimb, exact ca și cum acest lucru s-ar face fără ajax.

Înțeleg că trebuie să trimit interogarea către admin-ajax.php, dar cum?

0
Toate răspunsurile la întrebare 3
0

În sfârșit am reușit să rezolv.

Prima greșeală a fost să procesez aceeași funcție de două ori. Am apelat-o o dată după funcție și încă o dată în acțiunea ajax. Așa că, atunci când foloseam apelul ajax, funcția se executa de două ori. În exemplul din OP, acest lucru nu este deloc o problemă, pentru că este simplificat pentru a face doar un singur lucru, dar în codul meu real face mult mai multe și poate duce la pierderea de date nedorite.

De asemenea, aveam nevoie doar să opresc ajax-ul și să obțin un răspuns personalizat, nimic mai mult. Iată ce am făcut:

1. Am schimbat asta:

smk_remove_post();

în asta:

add_action('parse_query', 'smk_remove_post');

Este mai bine să rulezi funcția mai târziu, când este nevoie, într-o acțiune specială.

2. Apoi, am modificat handler-ul ajax: Am șters această linie smk_remove_post(); și am schimbat acțiunea ajax din wp_ajax_smk_remove_post_ajax în 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. Am redenumit string-ul de interogare reaction în action. L-am schimbat în URL și în funcție:

4. În final, am modificat scriptul jQuery. Acum folosește admin-ajax.php și trimite URL-ul ca date:

url: ajaxurl,
data: _this.attr('href'),

Iată codul final:

Link:

<a href="http://example.com/?action=smk_remove_post&id=1226&_nonce=7be82cd4a0" class="smk-remove-post">Șterge postarea</a>

Cod 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' ) ){
                // Șterge postarea
                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('Totul este în regulă, postarea a fost ștearsă.');
            }
        });
    });
}
smk_remove_post();

Edit: De asemenea, o mică actualizare la codul de mai sus. Pentru a procesa string-urile de interogare este necesar să ștergi calea site-ului, altfel pot apărea probleme neașteptate. Am adăugat asta la data href:

.split('?')[1]
31 mar. 2015 18:15:57
3

Faceți link-ul astfel

<a href="http://example.com/?reaction=smk_remove_post&id=1226&_nonce=7be82cd4a0" data-id="1226" data-nonce="7be82cd4a0" class="smk-remove-post">Șterge postarea</a>

Și 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')
    };

    // începând cu versiunea 2.8, ajaxurl este întotdeauna definit în header-ul adminului și trimite către admin-ajax.php
    jQuery.ajax({
        type: "GET",
        url: ajaxurl,
        data: data,
        success: function(response){
            console.log(response);
            _this.text('Totul este în regulă, postarea a fost ștearsă.');
        }
    });
});

Consultați Codex despre AJAX în Plugin-uri. Și în Codex, se spune:

În majoritatea cazurilor ar trebui să folosiți wp_die() în funcția de callback Ajax. Acest lucru oferă o integrare mai bună cu WordPress și facilitează testarea codului.

Deci folosiți wp_die(); în loc de die();

31 mar. 2015 16:52:32
Comentarii

Acesta este codul pe care l-am folosit înainte, dar aici am nevoie ca codul să funcționeze atât cu, cât și fără ajax.

Andrei Surdu Andrei Surdu
31 mar. 2015 17:06:39

Dacă dezactivez javascript-ul, va reveni la reîncărcarea paginii și va procesa acțiunea fără ajax. În exemplul tău, va funcționa doar dacă JS este activat.

Andrei Surdu Andrei Surdu
31 mar. 2015 17:07:46

Ok. Doar adaugă înapoi valoarea href și va funcționa. Dacă javascript-ul este dezactivat, atunci event.preventDefault nu va funcționa și va merge la acel link.

Rene Korss Rene Korss
31 mar. 2015 17:13:00
0

AJAX nu este magic și atunci când soliciți URL-ul X, vei primi același HTML pentru acel URL, indiferent dacă o faci din bara de adrese a browserului, dintr-un link sau prin AJAX. Prin urmare, dacă dorești un răspuns diferit de HTML, nu poți folosi același URL pentru cererea AJAX ca în cazul linkului.

WordPress are un „punct final” special pentru gestionarea cererilor AJAX - admin-ajax.php, iar toate cererile AJAX ar trebui trimise doar către acesta, ceva de genul $.ajax({url:....admin-ajax.php})

Apoi, trebuie să anunți WordPress ce dorești să faci, iar pentru aceasta există un parametru special în cerere numit action. Acest parametru va identifica hook-ul care va fi folosit pe partea de server pentru a gestiona cererea. Această parte ai făcut-o corect în codul tău.

Acum ai nevoie de parametri suplimentari care identifică ce obiect ar trebui manipulat sau returnat de operațiunea AJAX. Poți folosi permalink-ul postării sau ID-ul postării, de exemplu, dar totul depinde de complexitatea operațiunii pe care încerci să o realizezi. În cazul tău specific, aș presupune că un ID de postare ar fi cel mai bun parametru de trimis în cerere.

Cum să trimiți parametrii? Majoritatea oamenilor fac o cerere POST atunci când utilizează AJAX, dar dacă dorești o cerere GET, atunci poți să-i transmiți ca parte a URL-ului (ceea ce presupun că jQuery va face exact pentru tine).

31 mar. 2015 17:04:16