400 złych żądań na admin-ajax.php tylko przy użyciu haka akcji wp_enqueue_scripts


16

Ostatnio pracuję nad ajaxem. Samouczki, które znajdziesz w sieci, są bardzo podobne i dość łatwe do wdrożenia. Ale zawsze otrzymuję złe żądanie 400 w moim ajax-admin.phppliku.

Po długich i intensywnych poszukiwaniach dowiedziałem się, że dzieje się tak z powodu czasu integracji.

Jeśli initużyję haka akcji do zainicjowania skryptu i wp_localize_scriptwszystko działa dobrze. Więc sam kod musi być poprawny.

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' => 'REDIRECT_URL_HERE','loadingmessage' => __('Sending user info, please wait...')));
   add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
}

if(!is_user_logged_in()){
   add_action('init','ajax_login_init');
}

function ajax_login(){
    //nonce-field is created on page
    check_ajax_referer('ajax-login-nonce','security');
    //CODE
    die();
}

Ale jeśli użyję np. wp_enqeue_scriptsHaka akcji, zawsze otrzymam złą prośbę.

if(!is_user_logged_in()){
    add_action('wp_enqueue_scripts','ajax_login_init');
}

Problem polega na tym:

Chciałbym mieć funkcje w dodatkowym pliku php i ładować je tylko wtedy, gdy są potrzebne na konkretnej stronie. Do tego potrzebuję na przykład is_page(). Ale is_page()działa najwcześniej, kiedy podpinam funkcję z włącznikiem do parse_queryzaczepu akcji:

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');

Więc wtedy funkcje podpięte do initzaczepienia w my-page-test-functions.phppliku nie są uruchamiane, jak sądzę, ponieważ initsą wcześniejsze parse_query.

Czy istnieją najlepsze praktyki, aby to zorganizować, więc działa? Lub jak mogę naprawić admin-ajax.phpzłe żądanie podczas używania wp_enqeue_scriptshaka akcji?

Odpowiedzi:


13

Myślę, że jedyne, czego tu brakuje, to to, że musisz wyjść na add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');zewnątrz ajax_login_init.

Ten kod rejestruje program obsługi Ajax, ale kiedy go uruchomisz wp_enqueue_scripts, jest już za późno i wp_ajax_nopriv_haki są już uruchomione.

Więc spróbowałeś czegoś takiego:

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' => __('Sending user info, please wait...')));
}

add_action( 'wp_enqueue_scripts','ajax_login_init' );

add_action( 'wp_ajax_nopriv_ajaxlogin','ajax_login' );

function ajax_login(){
  //nonce-field is created on page
  check_ajax_referer('ajax-login-nonce','security');
  //CODE
  die();
}

Edytować:

Teraz jest bardziej jasne, że chcesz załadować JavaScript tylko na tej konkretnej stronie. Oznacza to, że musisz włożyć swoje is_page()wnętrze ajax_login_init(). Zaktualizowałem odpowiednio kod.

Dlaczego twoje rozwiązanie nie zadziałało?

is_page()Check oznaczało, że plik został załadowany tylko funkcje na tej stronie konkretnego. ajax_login_init()zostaje wywołany, a twoje skrypty kolejkowane. Jak na razie dobrze.

Teraz twój skrypt wykonuje wywołanie ajax. Jak wspomniano w komentarzach, wywołania ajax nie są świadome bieżącej strony, na której jesteś. Plik ma przyczynę wp-admin/admin-ajax.php. Nie ma WP_Queryi dlatego is_page()nie działa podczas żądania ajax.

Ponieważ to nie działa, sw18_page_specific_functions()nic nie zrobię w kontekście ajax. Oznacza to, że plik funkcji nie został załadowany, a Twój program obsługi ajax nie istnieje.

Dlatego zawsze musisz dołączyć ten plik funkcji i przenieść ten is_page()czek do środka ajax_login_init().

Zamiast więc sw18_page_specific_functions() { … }uruchomić include_once dirname(__FILE__).'/includes/my-page-test-functions.php';bezpośrednio. Bez żadnego add_action( 'parse_query' )połączenia.


Dobry pomysł. Zmieniłem to (wciąż ten sam błąd), ale problem nadal polega na tym, że plik zawierający funkcje ładuje się zbyt późno. Potrzebuję jednak sposobu na odróżnienie używanej strony. - obecnie próbuję tego za pomocą is_page () jak opisano powyżej.
Sin

Czy próbujesz uruchomić is_page()od wewnątrz ajax_login()lub od wewnątrz ajax_login_init(). Ten pierwszy nie może działać, ponieważ jest w kontekście Ajax.
swissspidy

Wymieniłem pliki, w których znajdują się funkcje, jako tekst opisowy powyżej. Funkcja is_page () jest używana w funkcji.php i służy do dołączania pliku z funkcjami ajax tylko wtedy, gdy jest to potrzebne.
Sin

@ Sin Znowu, is_page()nie działa w kontekście Ajax. Zaktualizowałem odpowiednio swoją odpowiedź.
swissspidy

0

Pamiętaj, aby do funkcji dodać nazwę funkcji „akcja” wp_ajax_.

function fetchorderrows() { // Want to run this func on ajax submit
  // Do awesome things here all day long
}

add_action('wp_ajax_fetchorderrows', 'fetchorderrows', 0);

-3

po prostu napisz umrzeć; na końcu jak poniżej ...wprowadź opis zdjęcia tutaj


8
Cześć Zee Xhan. Witamy na stronie. Twoja odpowiedź wymaga pewnych poprawek. Po pierwsze, jeśli Twoja odpowiedź to kod, nie publikuj zrzutu ekranu. Zamiast tego opublikuj kod jako fragment kodu i sformatuj go jako kod (użyj przycisku {}). To prawdopodobnie powód, dla którego Twoja odpowiedź została odrzucona i nie została zaakceptowana. Przydałoby się trochę więcej wyjaśnień - na przykład „dlaczego”, po prostu napisz die () i gdzie dokładnie to idzie w odniesieniu do kodu w OP (oryginalny post)?
butlerblog
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.