Ошибка ajax 400

I am trying to send an Ajax POST request using Jquery but I am having 400 bad request error.

Here is my code:

$.ajax({
  type: 'POST',
  url: "http://localhost:8080/project/server/rest/subjects",
  data: {
    "subject:title":"Test Name",
    "subject:description":"Creating test subject to check POST method API",
    "sub:tags": ["facebook:work", "facebook:likes"],
    "sampleSize" : 10,
    "values": ["science", "machine-learning"]
  },
  error: function(e) {
    console.log(e);
  }
});

It Says: Can not build resource from request.
What am I missing ?

asked Apr 15, 2013 at 13:57

Sachin Jain's user avatar

Sachin JainSachin Jain

21.2k32 gold badges100 silver badges167 bronze badges

4

Finally, I got the mistake and the reason was I need to stringify the JSON data I was sending. I have to set the content type and datatype in XHR object.
So the correct version is here:

$.ajax({
  type: 'POST',
  url: "http://localhost:8080/project/server/rest/subjects",
  data: JSON.stringify({
    "subject:title":"Test Name",
    "subject:description":"Creating test subject to check POST method API",
    "sub:tags": ["facebook:work", "facebook:likes"],
    "sampleSize" : 10,
    "values": ["science", "machine-learning"]
  }),
  error: function(e) {
    console.log(e);
  },
  dataType: "json",
  contentType: "application/json"
});

May be it will help someone else.

answered Apr 17, 2013 at 8:01

Sachin Jain's user avatar

Sachin JainSachin Jain

21.2k32 gold badges100 silver badges167 bronze badges

7

Yes. You need to stringify the JSON data orlse 400 bad request error occurs as it cannot identify the data.

400 Bad Request

Bad Request. Your browser sent a request that this server could not
understand.

Plus you need to add content type and datatype as well. If not you will encounter 415 error which says Unsupported Media Type.

415 Unsupported Media Type

Try this.

var newData =   {
                  "subject:title":"Test Name",
                  "subject:description":"Creating test subject to check POST method API",
                  "sub:tags": ["facebook:work", "facebook:likes"],
                  "sampleSize" : 10,
                  "values": ["science", "machine-learning"]
                  };

var dataJson = JSON.stringify(newData);

$.ajax({
  type: 'POST',
  url: "http://localhost:8080/project/server/rest/subjects",
  data: dataJson,
  error: function(e) {
    console.log(e);
  },
  dataType: "json",
  contentType: "application/json"
});

With this way you can modify the data you need with ease. It wont confuse you as it is defined outside the ajax block.

answered May 17, 2018 at 8:05

Du-Lacoste's user avatar

Du-LacosteDu-Lacoste

11.3k2 gold badges67 silver badges50 bronze badges

1

In case anyone else runs into this. I have a web site that was working fine on the desktop browser but I was getting 400 errors with Android devices.

It turned out to be the anti forgery token.

$.ajax({
        url: "/Cart/AddProduct/",
        data: {
            __RequestVerificationToken: $("[name='__RequestVerificationToken']").val(),
            productId: $(this).data("productcode")
        },

The problem was that the .Net controller wasn’t set up correctly.

I needed to add the attributes to the controller:

    [AllowAnonymous]
    [IgnoreAntiforgeryToken]
    [DisableCors]
    [HttpPost]
    public async Task<JsonResult> AddProduct(int productId)
    {

The code needs review but for now at least I know what was causing it. 400 error not helpful at all.

answered Mar 30, 2020 at 13:52

Norbert Norbertson's user avatar

The question is a bit old… but just in case somebody faces the error 400, it may also come from the need to post csrfToken as a parameter to the post request.

You have to get name and value from craft in your template :

<script type="text/javascript">
    window.csrfTokenName = "{{ craft.config.csrfTokenName|e('js') }}";
    window.csrfTokenValue = "{{ craft.request.csrfToken|e('js') }}";
</script>

and pass them in your request

data: window.csrfTokenName+"="+window.csrfTokenValue

answered Jan 21, 2017 at 16:17

Benoît Schiex's user avatar

1

You need to build query from «data» object using the following function

function buildQuery(obj) {
        var Result= '';
        if(typeof(obj)== 'object') {
            jQuery.each(obj, function(key, value) {
                Result+= (Result) ? '&' : '';
                if(typeof(value)== 'object' && value.length) {
                    for(var i=0; i<value.length; i++) {
                        Result+= [key+'[]', encodeURIComponent(value[i])].join('=');
                    }
                } else {
                    Result+= [key, encodeURIComponent(value)].join('=');
                }
            });
        }
        return Result;
    }

and then proceed with

var data= {
"subject:title":"Test Name",
"subject:description":"Creating test subject to check POST method API",
"sub:tags": ["facebook:work, facebook:likes"],
"sampleSize" : 10,
"values": ["science", "machine-learning"]
}

$.ajax({
  type: 'POST',
  url: "http://localhost:8080/project/server/rest/subjects",
  data: buildQuery(data),
  error: function(e) {
    console.log(e);
  }
});

answered Apr 15, 2013 at 14:05

Christian Ezeani's user avatar

2

I’m hoping this may be of use to those encountering 400 errors while using AJAX in WordPress going forward. Even though this question is many years old, the solutions provided have all been programmatic, and I’m sure many have stepped through their code to repeatedly find it’s correct, yet continue to find it is not working.

I found dozens of results asking how to resolve «WP AJAX request returning 400 Bad Request» or «WP AJAX request returning 0» and nothing today worked.

Googling «How do I fix 400 bad request on WordPress?» finally resulted in the answer appearing from https://wp-umbrella.com/troubleshooting/400-bad-request-error-on-wordpress/

Clear your Web Browser Cache and Cookies

You may be surprised, but most 400 errors in WordPress can be fixed by clearing your browser’s cache and cookies. Browser caches temporarily store images, scripts, and other parts of websites you visit to speed up your browsing experience.

Clearing both my cache and cookies saw the 400 Bad Request code disappear and results return AJAX results as expected.

answered Jun 23, 2022 at 8:24

Patrick Jackson's user avatar

and thank you in advance for helping me.

I’m trying to make a POST where I pass the TOKEN in the URL and I want to pass another param too so I can save the info in the DB. I have this:

    $("#btnAddCompany").click(function(e) {
    var token = "123";
    var companyValue = document.getElementById("companyValue").value;
    var obj ={CompanyId: 4 ,Name: companyValue }
    var postData = JSON.stringify(obj);
    console.log(postData);
      $.ajax({  
        type: "POST", //REQUEST TYPE
        dataType: "json", //RESPONSE TYPE
        contentType: "application/json",
        data: postData,
        url: "http://banametric.ddns.net/BanaMetricWebServices/BanaSov_WS.svc/CompanySave/"+token, 
        success: function(data) {
            toastr.success("Lidl Adicionado!");
        },
        error: function(err) {
            console.log("AJAX error in request: " + JSON.stringify(err, null, 2));
        }
    }).always(function(jqXHR, textStatus) {
        if (textStatus != "success") {
            alert("Error: " + jqXHR.statusText);
        }
    })
});

But I’m getting an 400 error (Bad Request) so I assume that I’m making something wrong, but I don’t find out what. The error trace is this:

AJAX error in request: { «readyState»: 4, «responseText»: «rn

The server encountered an error processing the request. The
exception message is ‘The incoming message has an unexpected message
format ‘Raw’. The expected message formats for the operation are
‘Xml’, ‘Json’. This can be because a WebContentTypeMapper has not been
configured on the binding. See server logs for more
details. The exception stack trace is:

rn

at
System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message
message, Object[] parameters)rn at

I have been delving into AJAX within WordPress and have followed many tutorials on how to do so, but every single request returns a 400 error.

In my functions.php I have added the following:

Step 1 — Register and add scripts to WordPress

/**
 * Initialize the JavaScript we need for loading more
 *
 * @return void
 */
function ajax_load_more_init()
{
    // Register and enqueue the script we need for load more
    wp_register_script('ajax-load-more-script', get_template_directory_uri() . '/assets/scripts/ajax-load-more.js', array('jquery'));
    wp_enqueue_script('ajax-load-more-script');

    // Localize the script so we can access tthe variables in PHP
    wp_localize_script('ajax-load-more-script', 'ajax_load_more_object', array(
        'ajax_url' => admin_url('admin-ajax.php'),
    ));
}

Step 2 — Enqueue the actual script

/**
 * Add AJAX loader to scripts
 */
add_action('wp_enqueue_scripts', 'ajax_load_more_init');

Step 3 — Allow AJAX to be used on the frontend

// AJAX Hook for users
add_action('wp_ajax_ajax_load_more', 'ajax_load_more');
add_action('wp_ajax_nopriv_ajax_load_more', 'ajax_load_more');

Step 4 — A dead simple function for testing

/**
 * The backend PHP to actually load more posts
 *
 * @return void
 */
function ajax_load_more()
{
    echo "TESTING";

    wp_die();
}

In my actual AJAX script I have the following:

jQuery(document).ready(function ($) {

  // Initialize Isotope as $grid
  const $grid = $('#grid').isotope({
    itemSelector: '.grid-item',
    percentagePosition: true,
    animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
    animationOptions: {
      duration: 800,
    },
    masonry: {
      columnWidth: '.grid-item',
      gutter: 30,
    },
  })


  var has_run = false;
  var init_offset = 0;

  // Hook into click event
  $('button.load-more-posts').click(function (e) {
    e.preventDefault();

    var button = $(this);
    var nonce = $(this).data("nonce");

    console.log('Nonce is: ' + nonce);

    // Disable the button
    button.prop("disabled", true);

    // Check the offset
    if (has_run == false) {
      button.data('offset', $(this).data("offset"));
      init_offset = $(this).data("offset");
    }

    console.log('Initial offset is: ' + init_offset);
    console.log('Initial offset is: ' + button.data('offset'));

    // Perform AJAX request
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: ajax_load_more_object.ajax_url,
      contentType: 'application/json; charset=utf-8',
      data: {
        action: 'ajax_load_more',
        security: nonce,
        init_offset: init_offset,
        offset: button.data('offset'),
      },
      beforeSend: function (xhr) {
        console.log('Loading more posts...')
        button.text('Loading');
      },
      success: function (response) {
        console.log(response);

        // Undo Button Disable
        button.prop("disabled", false);

        // Set Offset
        button.data("offset", offset + 10);

        // Script has run
        has_run = true;

        return false;
      },
      error: function (xhr, status, error) {
        console.log(xhr.responseText);
      }
    });
  });
});

As you can see in the $ajax call, the url is to admin-ajax and the action is the trailing part of wp_ajax_nopriv_ajax_load_more.

The nonce comes from the button on the front end like so:

<button class="load-more-posts" data-nonce="<?php echo wp_create_nonce('load_more_ajax'); ?>" data-offset="10">Load More Posts</button>

enter image description here

My working code

So, thanks to everyone’s shared input I was able to come up with a solution that I’ll detail below:

In functions.php (should really be in a plugin)

/**
 * Additional thumbnail sizes
 */
add_theme_support('post-thumbnails');
add_image_size('post-thumbnail-square', 300, 300, true);

/**
 * Initialize the JavaScript we need for loading more
 *
 * @return void
 */
function ajax_load_more_init()
{
    // Register and enqueue the script we need for load more
    wp_register_script('ajax-load-more-script', get_template_directory_uri() . '/assets/scripts/ajax-load-more.js', array('jquery'));
    wp_enqueue_script('ajax-load-more-script');

    // Localize the script so we can access tthe variables in PHP
    wp_localize_script('ajax-load-more-script', 'ajax_load_more_object', array(
        'ajax_url' => admin_url('admin-ajax.php'),
    ));
}

/**
 * Add AJAX loader to scripts
 */
add_action('wp_enqueue_scripts', 'ajax_load_more_init');

/**
 * Allow AJAX to be used on the front end
 */
add_action('wp_ajax_ajax_load_more_posts', 'ajax_load_more_posts_callback');
add_action('wp_ajax_nopriv_ajax_load_more_posts', 'ajax_load_more_posts_callback');

/**
 * The backend PHP to actually load more posts
 *
 * @return void
 */
function ajax_load_more_posts_callback()
{
    // First check the nonce, if it fails the function will break
    check_ajax_referer('ajax_load_more_posts', 'security');

    // Get the data we have from the load more button
    $offset = $_POST['offset'];
    $init_offset = $_POST['init_offset'];

    // Get posts with given offset
    if ($offset != null && absint($offset) && $init_offset != null && absint($init_offset)) {
        // Finally, we'll set the query arguments and instantiate WP_Query
        $args = array(
            'post_type' => 'post',
            'posts_per_page' =>  $init_offset,
            'offset' => $offset
        );

        $post_list = array();

        $query = new WP_Query($args);

        if ($query->have_posts()) :
            while ($query->have_posts()) : $query->the_post();

                //$categories = get_the_categories();

                $post_list[] = array(
                    'category' => get_the_category(),
                    'title' => get_the_title(),
                    'introduction' => get_field('introduction'),
                    'date' => get_the_date(),
                    'permalink' => get_permalink(),
                    'thumbnail' => get_the_post_thumbnail(),

                );
            endwhile;
        endif;

        echo json_encode($post_list);

        wp_die();
    }
}

In my ajax-loader script

jQuery(document).ready(function ($) {

  var has_run = false;
  var init_offset = 0;

  // Hook into click event
  $('button.load-more-posts').click(function (e) {

    var $grid = $('#grid').isotope({
      itemSelector: '.grid-item',
    });

    e.preventDefault();

    var button = $(this);
    var nonce = $(this).data("nonce");

    // Disable the button
    button.prop("disabled", true);

    // Check the offset
    if (has_run == false) {
      button.data('offset', $(this).data("offset"));
      init_offset = $(this).data("offset");
    }

    // Perform AJAX request
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: ajax_load_more_object.ajax_url,
      data: {
        action: 'ajax_load_more_posts',
        security: nonce,
        init_offset: init_offset,
        offset: button.data('offset'),
      },
      beforeSend: function (xhr) {
        console.log('Loading more posts...')
        button.text('Loading');
      },
      success: function (response) {
        console.log(response);
        button.text('Load more');

        // An array to store new items added via AJAX
        var new_items = [];

        // Run through JSON
        $.each(response, function (key, value) {

          var $new_item = $(`<div class="grid-item article-post-card ${value.category[0]['slug']}">
                                <a class="article-post-card__anchor" href=" ${value.permalink}" alt="${value.title}">
                                     <div class="article-post-card__featured-image-container">
                                        <div class="article-post-card__overlay"></div>
                                        <div class="article-post-card__featured-image">
                                            ${value.thumbnail}
                                        </div>

                                        <div class="article-post-card__category-label">
                                            ${value.category[0]['name']}
                                        </div>

                                    </div>

                                     <div class="article-post-card__content-wrapper">

                                        <div class="article-post-card__publish-date">
                                            <time class="updated" datetime="">${value.date}</time>
                                        </div>

                                        <div class="article-post-card__title">
                                            ${value.title}
                                        </div>

                                        <div class="article-post-card__excerpt">
                                          ${value.introduction}
                                        </div>

                                    </div>
                                </a>
                            </div>`);

          new_items.push($new_item[0]);
        });

        // Add the new items to the grid
        $grid
          .isotope('insert', new_items)
          .imagesLoaded().progress(function () {
            $grid.isotope('layout');
          });

        // Undo Button Disable
        button.prop("disabled", false);

        // Set Offset
        var offset = button.data("offset");
        button.data("offset", offset + 10);

        // Script has run
        has_run = true;

        return false;
      },
      error: function (xhr, status, error) {
        console.log("There was an error", error);
      }
    });
  });
});

If you guys could critique I think this would be useful for others too.

Reading Time: < 1 minute

I have spent the better part of 2 hours trouble shooting WordPress frontend ajax bad request issue. The wonderful error 400. I’ll show you how I fixed my issue as I didn’t find the WordPress or stack overflow communities particularly helpful.

Resolving the Bad Request Error

//....ENQUEUE YOUR JAVASCRIPT SCRIPT // Todo: edit the location of your javascript file. function rfr_public_enqueue_scripts() { wp_enqueue_script('rfr-ajax-public', plugins_url('public/assets/js/rfr-frontend.js', __FILE__), array('jquery'), NULL, true); wp_localize_script('rfr-ajax-public', 'rfr_ajax', array( 'url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('rfr_ajax_public_nonce'), )); } add_action('wp_enqueue_scripts', 'rfr_public_enqueue_scripts');

Code language: PHP (php)

The next part you need is the handler function. This can include whatever you want. It’s not special – it’s NAME is very special.

//...SET UP YOUR HANDLER FUNCTION function rfr_ajax_public() { if (!wp_verify_nonce($_POST['nonce'], 'rfr_ajax_public_nonce')) { error_log("Invalid or no nonce"); die(); } if (!$_POST['do']) die('No do do in your action.'); switch ($_POST['do']) { case 1: //do fetch echo json_encode(['status' => 'grand']); exit; break; } wp_die(); }

Code language: PHP (php)

In the second argument, you’ll find the name of our handler function.

//... add_action('wp_ajax_rfr_ajax_public', 'rfr_ajax_public'); add_action('wp_ajax_nopriv_rfr_ajax_public', 'rfr_ajax_public');

Code language: JavaScript (javascript)

When you do the javascript part, most articles lead me down a dark path of adding every ajax header, content-type and other attribute going. It seems that was all a waste of time. Thanks internet! You only need what is below

The ACTION must match your handler PHP FUNCTION. Can’t stress this enough. That was the key ingredient I was missing and wasted a large portion of my life resolving.

//... JAVASCRIPT $.ajax({ dataType: "json", type: "POST", url: rfr_ajax.url, data: { nonce: rfr_ajax.nonce, action: 'rfr_ajax_public', //payload: payload, //do: 1, }, success: function (resp) { console.log(resp); }, error: function (XMLHttpRequest, textStatus, errorThrown) { console.log(textStatus+" "+errorThrown); } });

Code language: JavaScript (javascript)

There is more you can do to get build this Ajax example up but hopefully it resolves your WordPress Ajax Bad Request Error

Every other day or so it seems, a new question is posted to one of the community
forums that cover ASP.NET Core Razor Pages asking why an AJAX post doesn’t
appear to work, or results in an HTTP 400 error. This article explains the most common cause, and
offers guidance on how to solve it.

The first step in diagnosing issues with AJAX requests is to actually examine
the request itself. There are many tools available for this, but the most
accessible tools are the developer tools provided by the major browsers.  They are
accessible from within Chrome, IE, Edge and Firefox by pressing F12 while viewing
your web page, or Ctrl+Shift+I in Opera. This latter key combination also works for
FireFox. In all cases, a panel should open in the browser that looks something
like this:

Browser developer tools

The highlighted elements are the Network tab, which is currently open and shows details of the browser’s network traffic, and the
All option which is selected by default. This option results in all network traffic being recorded and reported on. The option that sits to the right —
XHR — filters out all requests except those initiated by the XmlHttpRequest object or the browser’s Fetch API. In other words, if you select the XHR option, you will only see details of AJAX requests.

Once you have this panel open, you are in a much better position to fault
find. And the first potential point of failure to rule out is whether the AJAX
request is actually being made at all. If nothing appears in the grid, the
request is not being made. This could be for any number of reasons. If there is
an error in the JavaScript code, an inidcator will appear (arrowed, showing Chrome then Edge) and details will appear in the Console tab.

browser
browser

If there are no errors reported, but the request is still not made in
response to the trigger action, check to see if the event handler that initiates
the request is wired to the trigger element correctly. If the request is made,
details will appear, hopefully accompanied by a nice 200 HTTP status code to
signify that all has gone well. However, as alluded to in the title of this
article, the status code that causes the most confusion is 400:

HTTP 400

According to the HTTP standards:

The 400 (Bad Request) status code indicates that the server cannot or
will not process the request due to something that is perceived to be
a client error (e.g., malformed request syntax, invalid request
message framing, or deceptive request routing).

So there is an error in the way that the post request has
been constructed, but what is it? The most common cause for a 400 Bad Request
status code in Razor Pages is a missing Request Verification token.

Request Verification Tokens

Request verification is a process that ensures that post
requests received by your application originate from the application, and not
from a third party. Request verification is an important tool in the armoury
against

cross site request forgery (CSRF) attacks, and is enabled by default in Razor Pages.
A hidden form field named
__RequestVerificationToken is rendered within every form by the
form tag helper. It contains an encrypted token. The same value is included in a cookie which is sent with the form request. The presence of both of these
tokens and their values are validated when ASP.NET Core processes a POST request. If verification fails, the framework returns a
400 status code.

During normal form submission, the hidden field containing the CSRF token is automatically included in
the payload. The most common causes for failed AJAX posts resulting in a 400
status code are:

  • The CSRF token was generated but the  was not included in the
    posted payload
  • The CSRF token was included in the post, but in a way
    that prevented its discovery on the server.
  • No CSRF token was generated because the form tag helper was not used

No hidden field was generated

You need to generate a CSRF token value. While the form tag helper is the most
common means of generating the token value as a hidden field, it is not the only
means. In fact, it may not even make sense to generate form tags or hidden
fields for your scenario — espcially if you are not posting form field values.
If it does make sense to include a form in your page, then do so, but ensure
that the method attribute is set to post. CSRF
tokens are not generated for forms that use the get method.

If you don’t need a form, you can inject the IAntiforgery interface into your
page, and use it to generate a token value:

@page
@model MyApp.Pages.IndexModel
@inject IAntiforgery antiforgery
@{
    var token = antiforgery.GetAndStoreTokens(HttpContext).RequestToken;
}

You will need to either use the fully qualified namespace (Microsoft.AspNetCore.Antiforgery)
to reference IAntiforgery, or add a using statement to the
_ViewImports
file. The token can then be used in the AJAJX post.

Including the CSRF token in the post

You can construct the data for your AJAX post in any number of ways.
If you use jQuery, its serialize()
method will take care of ensuring that all the specified form values are
properly encoded for submission. When using the Fetch API, you can construct a
FormData object from the relevant form element, which will also
ensure that all fields, including hidden fields are included in the payload. You
may be doing this, but still your posts generate 400 codes. If so,
check to ensure that you are not stringifying your serialised form values to
JSON (using e.g. JSON.stringify) unnecessarily as this will prevent
the token being discovered by the server.

If you construct the values yourself, it is easy to overlook the verification
token.

The verification token can be included manually in the post in two ways, as part of
the request body, or in a header.

By default, the header must be named
RequestVerificationToken and the form field’s name must be __RequestVerificationToken,
although you can customise them through configuration via the
AntiforgeryOptions
in ConfigureServices e.g.

services.AddAntiforgery(o => o.HeaderName = "CSRF-TOKEN");

Acording to OWASP, inserting the CSRF token in the HTTP request header via JavaScript is considered more secure than adding the token in the hidden field form parameter.

If you are using jQuery, you can use the $.ajax method instead of
$.post, because it enables you access to more options, including setting headers:

$.ajax({
    type: "POST",
    url: "/",
    data: { foo: "bar" },
    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
    success: function (response) {
        ...

Here’s how you can accomplish the same thing using Fetch:

var token = document.querySelector('input[name="__RequestVerificationToken"]').getAttribute("value");
fetch("", {
    method: "post",
    headers: {
        "RequestVerificationToken": token
    },
    body: { foo: "bar" }
}).then(() => {
    ...
});

If the CSRF token is included as a form field and a header value, the header
value takes precedence. If the header value fails verification, the system will
not fall back to the form field. It will simpy return a BadRequestResult,
generating a 400 response code. 

Summary

This article provides some basic guidance on troubleshooting failing AJAX
post requests, and then focuses on the most common culprit in ASP.NET Core Razor
Pages. It explains what the CSRF token is, how it is generated by Razor Pages,
and how you can generate one using the IAntiforgery API. It also
explains how to manually include the token in your AJAX post so that it can be
discovered.

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Ошибка ais расшифровка
  • Ошибка airmatic w221
  • Ошибка airmatic visit workshop
  • Ошибка airf на бобкете

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии