admin管理员组

文章数量:1389768

I am working in a WordPress plugin. I need help in below AJAX code.

// On change division 
    $('body').on( 'change', '.division', function() {
        $.ajax({
            type: "POST",
            url:localData.statesurl,   //http://localhost/wordpress/wp-admin/admin-ajax.php
            data:{
                division: $(this).val(),  // I am getting value here.
                action: 'division_to_district_ajax'  //Do you need anything here ?
            },
            success:function(rss){
                console.log(rss);
                $('.district').empty();
                var $opt = '';  
                $.each( JSON.parse(rss), function(key, value) {
                    $opt += '<option value="'+key+'">'+value+'</option>';
                });
                $('.district').append($opt);
            },
            error: function (jqXHR, textStatus, errorThrown) { 
                   console.log(errorThrown);  // Bad Request
            },
            dataType: "json",
            cache: false,
            contentType: "application/json"
        });         
    });

From above code I am getting Bad Request in console.

I am attaching some screenshots of Network tab.

I am working in a WordPress plugin. I need help in below AJAX code.

// On change division 
    $('body').on( 'change', '.division', function() {
        $.ajax({
            type: "POST",
            url:localData.statesurl,   //http://localhost/wordpress/wp-admin/admin-ajax.php
            data:{
                division: $(this).val(),  // I am getting value here.
                action: 'division_to_district_ajax'  //Do you need anything here ?
            },
            success:function(rss){
                console.log(rss);
                $('.district').empty();
                var $opt = '';  
                $.each( JSON.parse(rss), function(key, value) {
                    $opt += '<option value="'+key+'">'+value+'</option>';
                });
                $('.district').append($opt);
            },
            error: function (jqXHR, textStatus, errorThrown) { 
                   console.log(errorThrown);  // Bad Request
            },
            dataType: "json",
            cache: false,
            contentType: "application/json"
        });         
    });

From above code I am getting Bad Request in console.

I am attaching some screenshots of Network tab.

Share Improve this question asked Mar 4, 2020 at 11:20 FoysalFoysal 4451 gold badge5 silver badges16 bronze badges 7
  • 1 where did you add action division_to_dustrict_ajax function?? – Chetan Vaghela Commented Mar 4, 2020 at 11:29
  • 1 What’s the code for handling the request? Have you looked at other questions about this error? The solution is always the same. – Jacob Peattie Commented Mar 4, 2020 at 11:30
  • 1 Did you add this code : function idonate_division_to_district_ajax() { if( isset( $_POST['division'] ) ){ echo json_encode( $_POST['division']); die(); } } add_action('wp_ajax_division_to_district_ajax', 'idonate_division_to_district_ajax' ); // executed when logged in add_action('wp_ajax_nopriv_division_to_district_ajax', 'idonate_division_to_district_ajax' ); // executed when logged out – Chetan Vaghela Commented Mar 4, 2020 at 11:35
  • 1 Is there a reason you used a legacy Admin AJAX endpoint instead of a modern REST API endpoint to do your AJAX calls? – Tom J Nowell Commented Mar 4, 2020 at 11:42
  • 1 Thanks @ChetanVaghela, your solution is working. Thanks. – Foysal Commented Mar 4, 2020 at 13:37
 |  Show 2 more comments

1 Answer 1

Reset to default 2

The problem is that it's sending JSON request headers, the old legacy Admin AJAX API doesn't understand this. As a result these are the cause of the bad request:

            dataType: "json",
            contentType: "application/json"

Your endpoint might be able to handle that input, but WP's admin AJAX handler can't, so it never knows which action to fire in the first place.

You have 2 options:

  • Remove these and adjust your AJAX handler accordingly
  • Switch to the modern REST API and get a proper endpoint URL that happily accepts JSON and returns JSON, and even encodes/validates/sanitises for you if told what to expect

Some additional notes:

  • $('body').on( 'change', '.division' is quite a broad event handler, I'd recommend limiting it down from the entire body tag to something more specific
  • There's no checking of the response to make sure it is what you think it is, the code just goes straight into JSON.parse
  • If no values are found or returned there's nothing to indicate that's what happened

But more importantly:

A Major Security Hole In The Code

Building up a HTML string by joining variables up together in JS then appending it is awful for security. It's one of the worst things code can do in javascript short of eval'ing code. Use DOM node construction instead and deal with DOM nodes, never HTML strings. Consider this a omgbbq high level priority fix. $( '<option>', { value: key, text: value } ) is what the code should be appending, it's much faster and safer.

Here's a secure version, the browser will automatically escape and sanitise the keys and make sure no malicious HTML gets snuck in:

const data = JSON.parse( rss );
const options = data.map( function ( key, value ) {
        return jQuery( '<option>', {
            value: key,
            text: value
        } );
} );
jQuery('.district').append( options );

It's also a little faster as the browser doesn't need to parse the HTML, and you don't have to worry about broken HTML markup either. Notice the data variable, we can now wrap it in an if statement and change behaviour if JSON parsing failed, or it doesn't contain what we expected it to. Never create HTML by joining up strings and variables, it's a major security issue, it's slow, and it's unnecessary.

本文标签: plugin developmentBad Request in AJAX