Получение CORS-ошибки только для DELETE-запроса (нет проблем с PUT, POST и GET) Проект DRF и React

Я сталкиваюсь со следующей ошибкой всякий раз, когда делаю запрос с моего react.js фронтенда. Я использую django DRF на бэкенде и nginx в качестве обратного прокси. Оба развернуты в облаке gcp и работают как разные сервисы. То есть фронтенд и бэкенд находятся в разных источниках, что и побудило меня включить политику CORS. Я довольно новичок в обеих технологиях.

Доступ к XMLHttpRequest по адресу 'https://backend-service/api/employee/' из origin 'https://frontend-service' был заблокирован политикой CORS: На запрашиваемом ресурсе отсутствует заголовок 'Access-Control-Allow-Origin'.

Странно то, что он выдает вышеуказанную ошибку, но элемент удаляется в базе данных.

Мой views.py,

@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])
def handle_crud_operations(request, SerializerClass):
    if not SerializerClass:
        return Response({'message': 'Invalid serializer specified'}, 
                      status=status.HTTP_400_BAD_REQUEST)

# GET method to retrieve all objects of the specified model
    if request.method == 'GET':
        model_objects = SerializerClass.Meta.model.objects.all()
        serializer = SerializerClass(model_objects, many=True)
        return Response({'message': 'Successfully retrieved data', 'data': 
                         serializer.data}, status=status.HTTP_200_OK)

# POST method to create a new object
    elif request.method == 'POST':
        serializer = SerializerClass(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'message': f'{SerializerClass.Meta.model.__name__} created 
            successfully', 'data': serializer.data}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# PUT method to update an object (full update)
    elif request.method == 'PUT':
        obj = get_object_or_404(SerializerClass.Meta.model, pk=request.data.get('id'))
        serializer = SerializerClass(obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'message': f'{SerializerClass.Meta.model.__name__} updated successfully', 'data': serializer.data}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# PATCH method to partially update an object
    elif request.method == 'PATCH':
        obj = get_object_or_404(SerializerClass.Meta.model, pk=request.data.get('id'))
        serializer = SerializerClass(obj, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({'message': f'{SerializerClass.Meta.model.__name__} updated successfully', 'data': serializer.data}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# DELETE method to delete an object
    elif request.method == 'DELETE':
        obj = get_object_or_404(SerializerClass.Meta.model, pk=request.data.get('id'))
        obj.delete()
        return Response({'message': f'{SerializerClass.Meta.model.__name__} deleted successfully'}, status=status.HTTP_204_NO_CONTENT)

    return Response({'message': 'Invalid request method'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)

@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']   
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def employee_operations(request):
   return handle_crud_operations(request._request, EmployeeDataSerializer)

nignx file backend,

# the upstream component nginx needs to connect to
upstream django {
   server unix:/djangoprj.sock; # for a file socket
}

server {
   # the port your site will be served on
   listen      8000;

   # the domain name it will serve for
   server_name https://backend-service; # substitute your machine's IP address or FQDN
   charset     utf-8;

   # set gzip compression
   gzip on;
   gzip_vary on;
   gzip_proxied any;
   gzip_http_version 1.1;
   gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

   # max upload size
   client_max_body_size 5M;   # adjust to taste

   # Django media
   location /static {
      alias /code/djangoprj/static;
   }

   # Finally, send all the rest to the Django server.
   location /api/ {
      uwsgi_pass  django;
      include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
      proxy_read_timeout 300;
      proxy_connect_timeout 300;
      proxy_send_timeout 300;
      send_timeout 300;

      # Handle CORS
      if ($request_method = 'OPTIONS') {
          add_header 'Access-Control-Allow-Origin' 'https://frontend-service' always;
          add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT, PATCH' always;
          add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With, X-CSRF-Token' always;
          add_header 'Access-Control-Allow-Credentials' 'true' always;
          return 204;
      }

      add_header 'Access-Control-Allow-Origin' 'https://frontend-service' always;
      add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT, PATCH' always;
      add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With, X-CSRF-Token' always;
      add_header 'Access-Control-Allow-Credentials' 'true' always;
   }
}

Мой запрос DELETE на фронтенде,

export function deleteEmployee(employeeId) {
  return axios.delete(`${backendUrl}/`, {
    data: { id: employeeId },
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Token ${token}`,
    }
  })
  .then(response => response.data);
}

settings.py

# Application definition
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "djangoprj_web",
    "rest_framework",
    "rest_framework.authtoken",
    "corsheaders",
]

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "djangoprj.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

WSGI_APPLICATION = "djangoprj.wsgi.application"

# CORS_ALLOWED_ORIGINS = [
#     "https://frontend-service-master-madmgxgaha-de.a.run.app",
# ]

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

CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

CORS_ALLOW_CREDENTIALS = False

Любая помощь будет оценена по достоинству. Пожалуйста, дайте мне знать, если потребуется что-то еще.

Вернуться на верх