8
votes

I have a strange and frustrating behaviour of wordpress admin-ajax.php file, when i make an ajax request it returns 400 error bad request.

(function( $ ) {
    var ajaxscript = { ajax_url : 'mydomain.com/wp-admin/admin-ajax.php' }
    $.ajax({
        url : ajaxscript.ajax_url,
        data : {
            action : 'cart_clb',
            id : 1
        },
        method : 'POST',
        success : function( response ){ console.log(response) },
        error : function(error){ console.log(error) }
    })
})(jQuery)

And inside my functions.php

add_action( 'wp_ajax_post_cart_clb', 'cart_clb' );
add_action( 'wp_ajax_nopriv_post_cart_clb', 'cart_clb' );

function cart_clb(){
    echo json_encode($_POST);
    die();
}

As said above when i execute the request :

mydomain.com/wp-admin/admin-ajax.php 400 (Bad Request)
{readyState: 4, getResponseHeader: ƒ, getAllResponseHeaders: ƒ, setRequestHeader: ƒ, overrideMimeType: ƒ, …}

Someone could help me to please? thank you.

7

7 Answers

15
votes

First, use full and absolute url, with protocol (or at least protocol-independent form):

var ajaxscript = { ajax_url : '//mydomain.com/wp-admin/admin-ajax.php' } 

Second, your ajax action name is not the php callback function name but the dynamic part of the hook wp_ajax_{action_name} / wp_ajax_nopriv_{action_name}, so in your case it should be:

data : {
    action : 'post_cart_clb',
    id : 1
},
8
votes

I have modified your code and look at this :

(function( $ ) {
var ajaxscript = { ajax_url : 'mydomain.com/wp-admin/admin-ajax.php' }
$.ajax({
    url : ajaxscript.ajax_url,
    data : {
        action : 'post_cart_clb',
        id : 1
    },
    method : 'POST', //Post method
    success : function( response ){ console.log(response) },
    error : function(error){ console.log(error) }
  })
})(jQuery)

This is the syntax of WordPress ajax : wp_ajax_{Your_action_name} wp_ajax_nopriv_{Your_action_name}

3
votes

In my case, I am using Class based approach. And I found the issue was because I was using wp_ajax_ request in constructor.

If you are using ajax methods inside class, move wp_ajax_ handles outside of class (write in main plugin file) and pass classname and method name. For example:

add_action( 'wp_ajax_your_handle', [ 'Class_Name', 'function_name' ] );
add_action( 'wp_ajax_nopriv_your_handle', [ 'Class_Name', 'function_name' ] ); 
1
votes

In Vanilla JavaScript You get a Bad Request if You don't append this header to the POST request:

request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');

So please be sure that jQuery appends as well that header.

1
votes
  1. in the url use /wp-admin/admin-ajax.php and try to have a local domain because with localhost or localhost/wordpress this might be weird, on the server this will work fine

  2. try to use fetch or XMLHttpRequest to have more control over the request and don't send data as json send it in a formData object const formData = new FormData();

     fetch(loader.ajax_url, {
         method: "POST",
         body: formData,
     }).then((resp) => {
             console.log(resp);
     }).catch((resp) => {
             console.log(resp);
     });
    

it is possible to have it work with other combinations but i find this almost perfect

0
votes

wp_ajax_nopriv_(action) executes for users that are not logged in. So, if you want it to fire on the front-end for both visitors and logged-in users, you can do this:

add_action( 'wp_ajax_my_action', 'my_action' ); // for loggin users

add_action( 'wp_ajax_nopriv_my_action', 'my_action' ); // for non loggin users

0
votes

Just Use

add_action( 'wp_ajax_my_action', 'my_action' );
add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

For more detail, check the below link
https://codex.wordpress.org/AJAX_in_Plugins