400 solicitação incorreta no admin-ajax.php usando apenas o gancho de ação wp_enqueue_scripts

15

Eu tenho trabalhado no ajax ultimamente. Os tutoriais que você encontra na rede são muito semelhantes e fáceis de implementar. Mas sempre recebo uma solicitação ruim 400 no meu ajax-admin.phparquivo.

Após uma pesquisa longa e intensiva, agora descobri que é por causa do tempo de integração.

Se eu usar o initgancho de ação para inicializar o script wp_localize_script, tudo funcionará bem. Portanto, o próprio código deve estar correto.

minha-página-teste-funções.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();
}

Mas se eu usar, por exemplo wp_enqeue_scripts, gancho de ação, sempre recebo a solicitação incorreta.

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

O problema com isso é:

Gostaria de ter as funções em um arquivo php extra e carregá-las somente se forem necessárias em uma página específica. Para isso eu preciso, por exemplo is_page(). Mas is_page()funciona o mais cedo possível quando eu conecto a função com o include no parse_querygancho de ação:

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

Então, funções conectadas para initconectar my-page-test-functions.phparquivos não são acionadas, suponho, porque initvem antes parse_query.

Existem práticas recomendadas para organizar isso, para que funcione? Ou como posso corrigir a admin-ajax.phpsolicitação incorreta ao usar o wp_enqeue_scriptsgancho de ação?

Pecado
fonte

Respostas:

13

Acho que a única coisa que falta aqui é que você precisa add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');sair ajax_login_init.

Esse código registra seu manipulador Ajax, mas quando você o executa apenas wp_enqueue_scripts, já é tarde demais e os wp_ajax_nopriv_ganchos já estão em execução.

Então, você já tentou algo assim:

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();
}

Editar:

Agora está mais claro que você deseja carregar apenas o JavaScript nessa página específica. Isso significa que você precisa colocar seu is_page()interior ajax_login_init(). Atualizei o código de acordo.

Agora, por que sua solução não funcionou?

A is_page()verificação significou que seu arquivo de funções foi carregado apenas nessa página específica. ajax_login_init()é chamado e seus scripts enfileirados. Por enquanto, tudo bem.

Agora, seu script faz a chamada ajax. Conforme mencionado nos comentários, as chamadas ajax não estão cientes da página atual em que você está. Há uma razão para o arquivo estarwp-admin/admin-ajax.php . Não existe WP_Querye, portanto is_page(), não funciona durante uma solicitação de ajax.

Como isso não funciona, sw18_page_specific_functions()não fará nada em um contexto ajax. Isso significa que seu arquivo de funções não está carregado e seu manipulador ajax não existe.

É por isso que você sempre deve incluir esse arquivo de funções e mover esse is_page() verificação para dentro ajax_login_init().

Então, em vez de sw18_page_specific_functions() { … }apenas executar include_once dirname(__FILE__).'/includes/my-page-test-functions.php';diretamente. Sem nenhuma add_action( 'parse_query' )ligação.

swissspidy
fonte
Boa sugestão. Eu mudei isso (ainda o mesmo erro), mas o problema ainda é que o arquivo que contém as funções será carregado tarde demais. Mas preciso de uma maneira de distinguir qual página é usada. - atualmente eu tento isso com is_page () como descrito acima.
Pecado
Você está tentando correr is_page()de dentro ajax_login()ou de dentro ajax_login_init(). O primeiro não pode funcionar porque está em um contexto Ajax.
swissspidy
Eu enumerei os arquivos nos quais as funções estão, como texto descritivo acima. O is_page () é usado no functions.php e serve para incluir o arquivo com as funções ajax somente quando necessário.
Sin
@ Sin Mais uma vez, is_page()não funciona em um contexto Ajax. Atualizei minha resposta de acordo.
swissspidy
0

Lembre-se de ter o nome da função 'action' anexado à wp_ajax_tag.

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
fonte
-3

apenas escreva morrer; no final, como abaixo ...insira a descrição da imagem aqui

ZEe XhAn
fonte
8
Oi Zee Xhan. Bem vindo ao site. Sua resposta precisa de algumas revisões. Primeiro, se sua resposta for código, não poste uma captura de tela. Em vez disso, publique o código como um snippet e formate-o como código (use o botão {}). Essa é provavelmente a razão pela qual sua resposta foi reduzida e não aceita. Além disso, um pouco mais de explicação seria útil - como "por que" basta escrever die (), e para onde exatamente isso acontece em relação ao código no OP (post original)?
butlerblog