7

I'm developing a plugin with an ajax handler. I first coded the ajax request setting up the XHR object. Looks like this:

var data = new FormData();
data.append('post_title', 'Hola como');
data.append('action', 'make_appointment');

var xhr = new XMLHttpRequest();

xhr.addEventListener('readystatechange', function() {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open('POST', 'http://wpapi.localdev/wp-admin/admin-ajax.php');
xhr.setRequestHeader('Cache-Control', 'no-cache');

xhr.send(data);

As you can notice I'm passing the action as part of the form data. This works fine but I wanted to use the fetch API instead because why not.

So I converted that to this:

let form = new FormData();
form.append('action', 'make_appointment');
form.append('post_title', 'hola como estas');

fetch(ajaxSettings.ajaxurl, {
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/form-data',
    'Cache-Control': 'no-cache'
  },
  body: form
})
  .then(response => {
    console.log(response);
    return response.text();
  })
  .then(response => {
    console.log(response);
  });

And this is not working, it just throws an 400 bad request error. I know that for some reason, the action parameter is not being sent correctly. Though, it works if, instead of sending the action as form data, I send it as a url parameter like this:

fetch(ajaxSettings.ajaxurl, {
  method: 'POST',
  headers: {
   'Content-Type': 'application/x-www-form-urlencoded',
   'Cache-Control': 'no-cache'
  },
  body: '?action=make_appointment'
})

What am I doing wrong here? I just want to make it work as the XHR request, i.e. sending the action as form data. Notice that the ajax handler on the WordPress side already exists and works correctly.

2
  • Have you found any working solution? Commented Jan 20, 2020 at 14:01
  • Do you need a nonce? Commented Oct 27, 2020 at 5:49

1 Answer 1

4

To make a working HTTP request with fetch API you have to do something like this.

const form = new FormData();
form.append('action', 'make_appointment');
form.append('post_title', 'hola como estas');
const params = new URLSearchParams(form);

fetch(ajaxSettings.ajaxurl, {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
       'Content-Type': 'application/x-www-form-urlencoded',
       'Cache-Control': 'no-cache',
      },
      body: params
    }).then(response => {
       return response.json();
    })
    .then(response => {
       // read data here
       console.log(response);
     }).catch(err => { 
       console.log(err);
     });
2
  • Worked, But why. they made it harder that jquery Commented Apr 30, 2022 at 14:49
  • Great answer. The important part in order to avoid error 400 is to pass data with new URLSearchParams.
    – Wtower
    Commented Apr 26, 2023 at 5:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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