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?

Grzech
źródło

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.

szwajcarski
źródło
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);
Mohd Abdul Mujib
źródło
-3

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

ZEe XhAn
źródło
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