9

I'm trying to remove jQuery from a React/Redux/Django webapp and replace the $.ajax method with the Fetch API. I've more or less got all my GET requests working fine and I seem to be able to hit my POST requests, but I cannot seem to format my request in such a way as to actually get my POST data into the Django request.POST object. Every time I hit my /sign_in view, the request.POST object is empty. My entire app's backend is built around using Django forms (no Django templates, just React controlled components) and I would really like to not have to rewrite all my views to use request.body or request.data.

Here is all the code I can think that would be relevant, please let me know if there's more that would be helpful:

This is the curried function I use to build my full POST data and attach the CSRF token:

const setUpCsrfToken = () => {
  const csrftoken = Cookies.get('csrftoken')

  return function post (url, options) {
  const defaults = {
    'method': 'POST',
    'credentials': 'include',
    'headers': {
      'X-CSRFToken': csrftoken,
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  }

  const merged = merge(options, defaults)
  return fetch(url, merged)
  }
}

export const post = setUpCsrfToken()

This is the API method I use from my React app:

export const signIn = data => {
  return post('/api/account/sign_in/', data)
}

The data when it is originally packaged up in the React app itself is as simple as an object with string values:

{
    email: 'email@email.com',
    password: 'password
}

I've looked at these questions and found them to be nominally helpful, but I can't figure out to synthesize an answer for myself that takes into account what I assume is some of the intricacies of Django:

Thanks!

Andy Swift
  • 2,179
  • 3
  • 32
  • 53
Nat Homer
  • 458
  • 4
  • 17

1 Answers1

8

You have to set the appropriate X-Requested-With header. jQuery does this under the hood.

X-Requested-With: XMLHttpRequest

So, in your example, you would want something like:

const setUpCsrfToken = () => {
  const csrftoken = Cookies.get('csrftoken')

  return function post (url, options) {
    const defaults = {
      'method': 'POST',
      'credentials': 'include',
      'headers': new Headers({
        'X-CSRFToken': csrftoken,
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With': 'XMLHttpRequest'
      })
    }

    const merged = merge(options, defaults)
    return fetch(url, merged)
  }
}