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