Bad Request in AJAX

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.