-1

I am creating a full-stack app with Django and React.

I created a component lookup in which I use cookies. This is my code:

  function getCookie(name) {
  var cookieValue = null;
  if (document.cookie && document.cookie !== '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
          var cookie = cookies[i].trim();
          if (cookie.substring(0, name.length + 1) === (name + '=')) {
              cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
              break;
          }
      }
  }
  return cookieValue;
}

function lookup(method, endpoint, callback, data) {
  let jsonData;
  if (data){
    jsonData = JSON.stringify(data)
  }
  const xhr = new XMLHttpRequest()
  const url = `http://localhost:8000/api${endpoint}`
  xhr.responseType = "json"
  const csrftoken = getCookie('csrftoken');
  xhr.open(method, url)
  xhr.setRequestHeader("Content-Type", "application/json")

  if (csrftoken){
    xhr.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest")
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
    xhr.setRequestHeader("X-CSRFToken", csrftoken)
  }
  
  xhr.onload = function() {
    callback(xhr.response, xhr.status)
  }
  xhr.onerror = function (e) {
    console.log(e)
    callback({"message": "The request was an error"}, 400)
  }
  xhr.send(jsonData)
}

export function createPost(newPost, callback){
  lookup("POST", "/posts/create/", callback, {content: newPost})
}

export function loadPosts(callback) {
    lookup("GET", "/posts/", callback)
}

This code results in this error in my frontend: (the backend works fine) Access to XMLHttpRequest at 'http://localhost:8000/api/posts/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field http_x_requested_with is not allowed by Access-Control-Allow-Headers in preflight response.

Now, I realized that if I delete this:

 if (csrftoken){
    xhr.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest")
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
    xhr.setRequestHeader("X-CSRFToken", csrftoken)
  }

My code works fine.

  1. Why is this happening? If there is anything more I should upload, let me know
  2. Do you think it is reasonable to skip csrftoken if it's just my personal project?

2 Answers2

1

First of all, is corsheaders installed in your django enviroment? if not install it by pip install django-cors-headers

Then in your settings.py add :

INSTALLED_APPS = [
...
'corsheaders',
...]

MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...]

CORS_ALLOWED_ORIGINS = [
"https://example.com", //ADD YOUR REACT IP IN THIS LIST
"https://sub.example.com",
"http://localhost:8080",
"http://127.0.0.1:9000"]

Then try to call your backend again, it should work now.

Mike
  • 342
  • 2
  • 6
  • Thanks for answering. It is installed and I have it all in my code. I am sorry for not mentioning this above. – frontendSO Aug 29 '20 at 19:30
  • Ok, maybe to focus better on the problem try using this extension : https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en if it works the problem is in the csrf – Mike Aug 30 '20 at 00:55
  • Okay, so I tested the CORS and CORS was not allowed for any request method. I added my browser to the whitelist and I do not have the error anymore. However, I think that my backend has a problem with dealing with submitted data. – frontendSO Aug 30 '20 at 04:48
  • Yes. I think my problem might be in the way I handle POST in my frontend. Anyway, thanks for the help :) – frontendSO Aug 30 '20 at 13:53
0

I had exactly the same issue. But what I did was to just add CORS_ALLOW_HEADERS in my settings.py and that's all:

**
CORS_ALLOW_HEADERS = ['*'] //This line did the magic for me
**  

With the following also:

INSTALLED_APPS = [
     ...
    'corsheaders',
     ...
]

MIDDLEWARE = [
     ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    ...
]

ALLOWED_HOSTS = ['*']

CORS_ALLOW_ALL_ORIGINS = True

The line below has to do with url that contains api like http://localhost:8000/api/anytext

CORS_URLS_REGEX = r'^/api/.*$'
Vishnu
  • 3,899
  • 2
  • 18
  • 19
Vicolas
  • 1
  • 3