web-dev-qa-db-ja.com

wp_enqueue_scriptsアクションフックのみを使用しているadmin-ajax.phpでの400の悪いリクエスト

私は最近ajaxに取り組んでいます。あなたがネット上で見つけたチュートリアルはすべてとてもよく似ていて、そして実装するのがとても簡単です。しかし、私はいつもajax-admin.phpファイルに 悪いリクエスト400 を出しています。

長く集中的に検索した結果、統合の時期が原因であることがわかりました。

initアクションフックを使用してスクリプトとwp_localize_scriptを初期化すると、すべてうまくいきます。そのため、コード自体は正しくなければなりません。

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

しかし私が使うならwp_enqeue_scriptsアクションフック私はいつも悪い要求を受けます。

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

これに関する問題は以下のとおりです。

これらの関数を追加のphpファイルに入れておき、それらが特定のページで必要な場合にのみそれらをロードしたいと思います。これには、たとえばis_page()が必要です。しかし、is_page()は、parse_queryアクションフックにインクルードして関数をフックすると、最も早く動作します。

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

それでmy-page-test-functions.phpファイルのinitフックにフックされた関数は起動されません、initparse_queryより前に来るので私は思います。

これを整理するためのベストプラクティスはありますか。それともadmin-ajax.phpアクションフックを使用しているときにどうやってwp_enqeue_scriptsの悪いリクエストを修正できますか?

12
Sin

ここで欠けているのは、add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');ajax_login_initの外に移動する必要があるということだけです。

そのコードはあなたのAjaxハンドラを登録します、しかしあなたがそれをwp_enqueue_scripts上でのみ実行するとき、それはすでに遅すぎて、そしてwp_ajax_nopriv_フックはすでに実行されています。

だから、あなたはこのようなことを試してみました:

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

編集:

その特定のページにJavaScriptをロードするだけでよいことがより明確になりました。これはis_page()ajax_login_init()の中に入れる必要があることを意味します。それに応じてコードを更新しました。

さて、なぜあなたの解決策はうまくいきませんでしたか?

is_page()チェックはあなたのfunctionsファイルがその特定のページにのみロードされたことを意味しました。 ajax_login_init()が呼び出され、あなたのスクリプトがエンキューされます。ここまでは順調ですね。

今すぐあなたのスクリプトは、Ajax呼び出しを行います。コメントで述べたように、ajaxの呼び出しは現在のページを認識していません。ファイルがwp-admin/admin-ajax.phpにある理由があります。 WP_Queryがないので、is_page()はajaxリクエストの間は機能しません。

それがうまくいかないので、sw18_page_specific_functions()はajaxのコンテキストでは何もしません。これは、あなたの関数ファイルがロードされておらず、あなたのajaxハンドラが存在しないことを意味します。

そのため、その関数ファイルを常にインクルードし、そのis_page()チェックをajax_login_init()内に移動する必要があります。

そのため、sw18_page_specific_functions() { … }の代わりに直接include_once dirname(__FILE__).'/includes/my-page-test-functions.php';を実行してください。 add_action( 'parse_query' )呼び出しなしで。

11
swissspidy

wp_ajax_タグに 'action'関数名を追加するのを忘れないでください。

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

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