Почему я получаю ошибку CORS Причина: запрос CORS не удался

#python #amazon-web-services #cors #fastapi

#python #amazon-веб-сервисы #корс #быстрый api #amazon-web-services #cors #fastapi

Вопрос:

Я разрабатываю изящное приложение, которое использует серверную часть FastAPI для взаимодействия с базой данных PostgreSQL, которая является локальной для моей организации, а не для моего экземпляра AWS EC2.

Я использую javascript fetch api для отправки запросов на мой серверный сервер для запроса базы данных для различных целей, на моем локальном компьютере все эти запросы принимаются с обоих концов, однако на AWS запросы от моего интерфейса даже не распознаются серверной частью fastAPI.

Я довольно неопытен в настройке подобных серверов, поэтому я предполагаю, что в моей настройке этих серверов есть какая-то основная ошибка, которая делает невозможным обмен данными между ними на AWS подобным образом.

Код fastapi выглядит следующим образом:

 import uvicorn
from fastapi import (Depends, FastAPI, HTTPException, Query,
                     Request)
from fastapi.middleware.cors import CORSMiddleware


app = FastAPI(debug=True)

origins = [
    '*'
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def root():
    return {"message": "Hello World"}

if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)
  

Мои запросы на выборку обычно выглядят следующим образом:

 const endpoint = public_IP:8000   `/`;

let objs = [];

fetch(endpoint)
    .then(response => {
        if (!response.ok) {
            throw Error(response.statusText);
        }
        return response.json();
    })
  

Когда я отправляю запрос на выборку, подобный приведенному выше, я получаю ошибку CORS с причиной: запрос CORS не удался. Сервер FastAPI, не имеет обратной связи, запрос, похоже, никогда не доходит до него, я не уверен почему. Насколько я знаю, обычно это связано с проблемами между запросами с использованием HTTP и HTTPS, но они, похоже, не имеют отношения к моей проблеме, поскольку ни одна часть моей настройки не использует HTTP. При использовании Chrome я получаю сообщение об ошибке: Также не удалось загрузить ресурс: net::ERR_CONNECTION_REFUSED.

Мои группы безопасности AWS для моего экземпляра EC2 разрешают трафик TCP с любого IP на порты 5000 и 8000. Именно там размещены мои два приложения, Svelte и FastAPI соответственно.

Ответ №1:

Скорее всего, ваша конечная точка в приложении fastapi вызывает исключение. Когда это возникает, CORSMiddleware установленный via app.add_middleware(...) не видит никакого HTTP-ответа и не имеет возможности выполнить свою работу с HTTP-ответом, созданным обработчиком ошибок FastAPI.

Решение заключается в том, чтобы обернуть все приложение FastAPI с помощью CORSMiddleware, как в :

 import uvicorn
from fastapi import (Depends, FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware


app = FastAPI(debug=True)

origins = [
    '*'
]


@app.get("/")
async def root():
    return {"message": "Hello World"}


app = CORSMiddleware(
    app=app,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=8000)
  

Ответ №2:

Краткие сведения

Ошибки CORS иногда могут быть настолько запутанными, потому что сообщения об ошибках недостаточно ясны, и существует множество возможных решений.

Первая возможность

  • Если вы загружаете свою страницу с данного хоста, в вашем случае 0.0.0.0 , а затем пытаетесь отправить запрос, например, на другой хост 127.0.0.1 , запрос блокируется для предотвращения XSS-атак

Изменение вашего хоста с 0.0.0.0 на 127.0.0.1 должно исправить это.

Вторая возможность

Если вы Mozillian, в Mozilla есть ошибки [см., см.], но в этом случае ваш код должен работать в другом браузере

Решение: Вы должны включить сертификат на каждом порту индивидуально.

Другие возможности

Попробуйте изменить свою конечную точку так

 const endpoint = public_IP:8000   `/`;
  

к этому

 const endpoint = `/`;