0

I am using Django for my backend and React for my Frontend. When I try to send a POST request, I receive :

Access to XMLHttpRequest at 'http://localhost:8000/package/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-methods is not allowed by Access-Control-Allow-Headers in preflight response.

I have combined a lot of answers that I found such as How to use csrf_token in Django RESTful API and React? and Django and React: csrf cookie is not being set in request header but still no luck.

  1. 'corsheaders' is in my INSTALLED APPS
  2. Middleware settings
MIDDLEWARE = [
    
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',

    'corsheaders.middleware.CorsMiddleware',
    
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',

    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
  1. CORS settings:
CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_METHODS = [
    "DELETE",
    "GET",
    "OPTIONS",
    "PATCH",
    "POST",
    "PUT",
]

CORS_ORIGIN_WHITELIST = (
'http://localhost:3000',
)

CORS_ALLOWED_ORIGINS = [
    'http://localhost:3000',
]

CSRF_TRUSTED_ORIGINS = ['http://localhost:3000']

from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = default_headers + ('cache-control',)
  1. Django view.py
from django.shortcuts import render
from django.views.generic.edit import CreateView
from .forms import PackageForm

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie

class PackageFormView(CreateView):

    form_class = PackageForm
    initial = {'key': 'value'}
    template_name = 'package_form.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class(initial=self.initial)
        return render(request, self.template_name, {'form': form})

    @method_decorator(ensure_csrf_cookie)
    def post(self, request, *args, **kwargs):

        form = self.form_class(request.POST)
        if form.is_valid():

            form.save()

        return render(request, self.template_name, {'form': form})
  1. React call
var csrftoken = getCookie("csrftoken");

    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 = jQuery.trim(cookies[i]);
          if (cookie.substring(0, name.length + 1) === name + "=") {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
          }
        }
      }
      return cookieValue;
    }

    const cors = {
      "X-CSRFToken": csrftoken,
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods":
        "POST, GET, PUT, DELETE, OPTIONS, HEAD, authorization",
      "Access-Control-Allow-Headers": "*",
      "Content-type": "application/json",
      "withCredentials": "true",
    };

    axios
      .post(
        baseURL,
        {
          title: "title from react",
          description: "description from react",
          "withCredentials": "true",
        },
        {
          headers: cors,
        }
      )
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
  };

I have already spent about 10 hours on this, I still can't find how to fix it.

Vincent Roye
  • 2,751
  • 7
  • 33
  • 53
  • If you check your error it says ***`Request header field access-control-allow-methods is not allowed by Access-Control-Allow-Header`*** means you're sending invalid `access-control-allow-methods` – Ankit Tiwari Dec 17 '22 at 04:54
  • I can see you've passed `authorization` inside `Access-Control-Allow-Methods` which is not a valid [HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) method. – Ankit Tiwari Dec 17 '22 at 04:56
  • Your **`Access-Control-Allow-Methods`** values shold contain in **`CORS_ALLOW_METHODS`** list if it's not then it will raise above error – Ankit Tiwari Dec 17 '22 at 04:57
  • I have aligned the Access-Control-Allow-Methods on both side, but the problem persists – Vincent Roye Dec 17 '22 at 05:04
  • Did you removed `authorization` from from both side? – Ankit Tiwari Dec 17 '22 at 05:06
  • In your frontend JavaScript/React code that’s making the request, completely remove all the `Access-Control-Allow-*` headers. Those are all response headers, not request headers. The exact cause of the error message in the question is that your frontend code is sending an `Access-Control-Allow-Methods` request header that it should not be. – sideshowbarker Dec 17 '22 at 06:05
  • Removing all the `Access-Control-Allow-*` headers from your frontend JavaScript/React code will resolve the problem described in the question as currently written. If, after removing those `Access-Control-Allow-*` headers from your frontend JavaScript/React code, you’re then getting another error, then you can then create a separate new question describing whatever the error you’ve run into at that time may be. – sideshowbarker Dec 17 '22 at 06:10
  • After removing all the Access-Control-Allow-* headers, I am now facing this issue "Forbidden (CSRF cookie not set.): /package/" (from Django) and "POST http://localhost:8000/package/ 403 (Forbidden)" from Chrome – Vincent Roye Dec 17 '22 at 07:28
  • I think I solved the previous problem. Now I receive: has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response even with changing the CORS_ALLOW_HEADERS to : CORS_ALLOW_HEADERS = ('content-disposition', 'accept-encoding', 'content-type', 'accept', 'origin', 'authorization') – Vincent Roye Dec 17 '22 at 07:54
  • PROBLEM SOLVED: var formData = new FormData(); formData.append('title', 'title from react'); ... axios({ method:'post', url: baseURL, headers:{ "Content-type": "multipart/form-data", "X-CSRFToken": csrftoken, } , data: formData, xsrfCookieName: csrftoken, xsrfHeaderName: 'X-CSRFTOKEN', withCredentials: true, }) CORS_ALLOW_HEADERS = ('content-disposition', 'accept-encoding', 'content-type', 'accept', 'origin', 'authorization','x-csrftoken') – Vincent Roye Dec 17 '22 at 08:27

0 Answers0