Я создал внутренний сервер в Django с Django Rest Framework и интерфейсом React.Мой фронт извлекает данные сзади через API.Каждое приложение находится в отдельном поддомене того же домена.Я использую Cloudflare для управления DNS и для SSL / безопасности.
У меня не было проблем с вызовами GET.Для вызовов POST я отправляю данные POST на сервер через форму, и я знаю, что это работает, поскольку есть изменения в базе данных (запись, созданная в этом случае).Тем не менее, я реализовал функцию «повторить до», используя axios и polly-js.Этот метод ждет, пока не получит ответ CREATED 201, в противном случае повторяется попытка.
Моя проблема заключается в том, что когда я отправляю форму в React, POST действительно принимается и обрабатывается моим внутренним сервером, но ответ блокируется.Таким образом, через 10-15 секунд я получаю сообщение об ошибке через консоль, и мой метод retry before отправляет другой запрос POST.Ответ этого второго не заблокирован Chrome, и я получаю статус 201.Но общий эффект состоит в том, что у меня теперь есть 2 идентичные записи в базе данных, потому что первый вызов не «получил» ответ и повторил попытку.
Ошибка в консоли, которую я получаю:
Access to XMLHttpRequest at 'https://subdomain.domain.io/' from origin 'https://api.domain.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
То, что я уже сделал и не сработало:
- IНе думайте, что это проблема с бэкэндом, поскольку POST проходит и запись создается.Но я внес в белый список все источники CORS в Django
- Я добавил заголовок 'Access-Control-Allow-Origin': '*' в мой запрос POST через axios
- Я вручную добавилтот же заголовок 'Access-Control-Allow-Origin': '*' из моего ответа Django DRF.
Оба запроса, которые я отправляю (первый - через отправку формы, второй - через автоматическую повторную попытку) идентичны (просматривается на вкладке Chrome network):
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Origin: https://subdomain.domain.io
Referer: https://subdomain.domain.io/path
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Мой метод POST и способ повторной попытки:
const postData = (url, data, headers) => {
headers['Access-Control-Allow-Origin'] = "*"
return polly()
.waitAndRetry([100, 200, 400, 1000])
.executeForPromise(async () => {
const rsp = await axios.post(url, data, headers);
if (rsp.status < 210) {
return rsp.data;
}
return Promise.reject(rsp);
});
};
Ответ Iполучить, когда вторая попытка удалась:
access-control-allow-origin: *
allow: GET, POST, HEAD, OPTIONS
cf-ray: 4dd7cbccce256948-CDG
content-length: 364
content-type: application/json
date: Mon, 27 May 2019 11:54:47 GMT
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
status: 201
strict-transport-security: max-age=2592000; includeSubDomains; preload
vary: Accept, Origin
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
Для справки, настройки CORS в Django
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_otp.middleware.OTPMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'access-control-allow-origin'
)
РЕДАКТИРОВАТЬ
Firefox показывает мне ответ для 504 GATEWAY TIMEOUT первого запроса POST:
cf-ray: 4dd82ac15f42cd97-CDG
content-type: text/html; charset=UTF-8
date: Mon, 27 May 2019 13:00:36 GMT
expect-ct: max-age=604800, report-uri="ht….com/cdn-cgi/beacon/expect-ct"
expires: Thu, 01 Jan 1970 00:00:01 GMT
pragma: no-cache
server: cloudflare
set-cookie: __cfduid=d0a3a9ee872171ada14cb…n=.wisly.io; HttpOnly; Secure
set-cookie: cf_use_ob=0; path=/; expires=Mon, 27-May-19 13:01:06 GMT
strict-transport-security: max-age=2592000; includeSubDomains; preload
x-content-type-options: nosniff
X-Firefox-Spdy: h2
Access-Control-Allow-Origin отсутствует, но он является частью моего внутреннего кода.Может ли что-нибудь происходить с Cloudflare?
Ожидаемый результат будет таким: когда я отправляю POST через форму, получаю обратно 201 (что будет принято и прочитано Chrome), чтобы я мог
- Показать пользователяформа была правильно сохранена в базе данных
- Не повторять POST, что приводит к двойной записи.
Спасибо!