12

I've been working on ajax lately. The tutorials you find on the net are all very similar and quite easy to implement. But I always get a bad request 400 on my ajax-admin.php file.

After a long and intensive search, I have now found out that's because of the time of integration.

If I use the init action hook to initialize script and wp_localize_script, everything works fine. So the code itself must be correct.

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

But if I use e.g. wp_enqeue_scripts action hook I always get the bad request.

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

The problem with this is:

I would like to have the functions in an extra php file and load them only if they are needed on a particular page. For this I need, for example is_page(). But is_page() works at the earliest when I hook the function with the include into the parse_query action hook:

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

So then functions hooked to init hook in my-page-test-functions.php file does not triggered, I suppose, because init comes before parse_query.

Is there a best practices to organize this, so it works? Or how can I fix the admin-ajax.php bad request when using the wp_enqeue_scripts action hook?

11

I think the only thing missing here is that you need to move add_action('wp_ajax_nopriv_ajaxlogin','ajax_login'); outside ajax_login_init.

That code registers your Ajax handler, but when you only run it on wp_enqueue_scripts, it's already too late and wp_ajax_nopriv_ hooks are already run.

So, have you tried something like this:

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

Edit:

Now it's more clear that you only want to load the JavaScript on that particular page. This means you need to put your is_page() inside ajax_login_init(). I've updated the code accordingly.

Now, why didn't your solution work?

The is_page() check meant that your functions file was only loaded on that specific page. ajax_login_init() gets called and your scripts enqueued. So far so good.

Now your script makes the ajax call. As mentioned in the comments, ajax calls are not aware of the current page you're on. There's a reason the file sits at wp-admin/admin-ajax.php. There's no WP_Query and thus is_page() does not work during an ajax request.

Since that does not work, sw18_page_specific_functions() won't do anything in an ajax context. This means your functions file is not loaded and your ajax handler does not exist.

That's why you need to always include that functions file and move that is_page() check inside ajax_login_init().

So instead of sw18_page_specific_functions() { … } just run include_once dirname(__FILE__).'/includes/my-page-test-functions.php'; directly. Without any add_action( 'parse_query' ) call.

  • Good suggestion. I have changed that (still the same error), but the problem still is that the file containing the functions will load too late. But I need a way to distinguish which page is used. - currently I try this with is_page () as described above. – Sin Jan 17 '18 at 11:04
  • Are you trying to run is_page() from within ajax_login() or from within ajax_login_init(). The former can't work because it's in an Ajax context. – swissspidy Jan 17 '18 at 12:05
  • I have enumerated the files in which the functions are, as descriptive text above. The is_page() is used in the functions.php and serves to include the file with the ajax functions only when needed. – Sin Jan 17 '18 at 12:48
  • @Sin Again, is_page() does not work in an Ajax context. I have updated my answer accordingly. – swissspidy Jan 17 '18 at 12:58
0

Remember to have the 'action' function name appended to the 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);
-3

just write die; at the end like below...enter image description here

  • 7
    Hi Zee Xhan. Welcome to the site. Your answer needs some revisions. First, if your answer is code, don't post a screenshot. Instead, post the code as a snippet and format it as code (use the {} button). That's likely the reason your answer was downvoted and not accepted. Also, a little more explanation would be helpful - like "why" just write die(), and where exactly does this go in relation to the code in the OP (original post)? – butlerblog Nov 12 '18 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.