user270199
user270199

Reputation: 1417

How can I enable CORS in FastAPI?

I'm trying to enable CORS in this very basic FastAPI example, however it doesn't seem to be working.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*']
)

@app.get('/')
def read_main():
    return {'message': 'Hello World!'}

This is the response I get:

curl -v http://127.0.0.1:8000
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Fri, 08 Jan 2021 19:27:37 GMT
< server: uvicorn
< content-length: 26
< content-type: application/json
<
* Connection #0 to host 127.0.0.1 left intact
{"message":"Hello World!"}*

Upvotes: 100

Views: 169321

Answers (5)

Speech-To-Text.Cloud
Speech-To-Text.Cloud

Reputation: 43

If the (browser) client makes a request from a local file (e.g. file://.../main.html), we run into an edge case. The request origin must then be specified as 'null', when requesting with credentials included.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware, Response

app = FastAPI()
app.add_middleware(
    CORSMiddleware, allow_origins=['null'],
    allow_credentials=True, allow_methods=['*'], allow_headers=['*'])

@app.get('/')
def main():
    return Response('OK', status_code=200)

You can see the origin of the request in the error message of the browser console, if running a chromium-based browser. In Firefox however, the origin is hidden.

Please note that this has security implications, and it is thus not recommended. See this related answer for more details: https://stackoverflow.com/a/78006792/23263766.

Upvotes: 1

BHASKAR
BHASKAR

Reputation: 97

Adding expose_headers helped me to fix this

expose_headers=["*"]

Upvotes: 2

Joe
Joe

Reputation: 7131

I had a similar issue and just found the solution. Using lots of copypasted code, I was spinning up another FastAPI instance somewhere where CORS was not configured, like this:

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*']
)

... much later somewhere within lots of green code ...
app = FastAPI()

Upvotes: 4

noname2048
noname2048

Reputation: 137

In my case, CORS not works when pydantic or type problems occured.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:3000",
]

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

# works well!
@app.get("/list")
async def main():
    return ["hi", "hello"]

# error cases
from typing import List
from app.nosql.model import Book

@app.get("/error")
async def main():
    # case 1
    ret = mongo_db.engine.find(Book, limit=10) # keyword "await" missing
    return ret  # CORS 500 error
    # case 2
    ret: List[Book] = await mongo_db.engine.find(Book, limit=10) # data was not fit with model Book
    return ret # CORS error
    # case 3
    return ["hi", "hello"] # works well...

Whats the server-side error says? It might be error occurs in server. How about test with new function. (has no error) If server works well.. humm.. sry about that.

Upvotes: 12

yuanzz
yuanzz

Reputation: 1968

you can find answer from this:fastapi cors

then this is a very simple code to achieve it:

  1. create a python file and named it main.py.

  2. add code in this file.

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = ["*"]

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


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

and run this app:

uvicorn main:app  --reload --host 0.0.0.0 --port 8000

if you computer ip is 192.12.12.12

you can check this link and just write a small javascript in html:

<script>
        fetch("http://192.12.12.12:8000/").then((Response) => {
            return Response.json()
        }).then((data) => {
            console.log(data);
        })
    </script>

Upvotes: 135

Related Questions