According to [1], Content-Type is always allowed for CORS requests. This is not true, see the test below.
[1] https://fastapi.tiangolo.com/tutorial/cors/#use-corsmiddleware
Steps to reproduce the behavior with a minimum self-contained file.
Replace each part with your own scenario:
test_cors.py with:
Toggle to view
import pytest
from fastapi import FastAPI
from starlette import status
from starlette.middleware.cors import CORSMiddleware
from starlette.testclient import TestClient
app = FastAPI()
app.add_middleware(CORSMiddleware)
@app.post(path='/dummy')
def dummy():
...
@pytest.fixture
def client():
yield TestClient(app)
def test_content_type_is_always_allowed_for_cors_requests(client):
# arrange
request_headers = {
"Origin": "https://www.google.de",
"Access-Control-Request-Method": "POST",
"Access-Control-Request-Headers": "Content-Type",
}
# act
response = client.options('/', headers=request_headers)
# assert
assert response.status_code == status.HTTP_200_OK
pytest test_cors.pyThe Content-Type header is whitelisted as per the documentation.
n/a
I noticed that the CORSMiddleware is coming straight from Starlette, so I would need to create an issue there, as well.
Did miss the allow_headers=["*"], kwargs?
Yes, I did not add this because the docs state: "The Accept, Accept-Language, Content-Language and Content-Type headers are always allowed for CORS requests."
I consider "always" to be unconditional. Am I wrong here?
For default CORS, I think you shouldn't add the code app.add_middleware(CORSMiddleware)
My understanding is that without the CORSMiddleware, no CORS is enabled at all.
The section:
The Accept, Accept-Language, Content-Language and Content-Type headers are always allowed for CORS requests.
It doesn't mean that something will automatically return the Allow-X headers without a middleware, it means that browsers, the ones that actually do all the CORS dance, don't require those headers to do CORS (cross-origin resource sharing). So, browsers don't even trigger an OPTIONS request before one with those headers.
I think it would be useful for you to read the docs about CORS in MDN to understand how all that works: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Thanks for explaining!
Thanks @tiangolo
I wonder if it would be clearer if we change the docs to say,
The Accept, Accept-Language, Content-Language and Content-Type headers are always allowed for simple CORS requests.
I too had the misunderstanding that I would not have to explicitly specify those headers regardless of the kind of CORS request the server is expecting. I can create a PR if the doc change is OK with you.
Most helpful comment
The section:
It doesn't mean that something will automatically return the
Allow-Xheaders without a middleware, it means that browsers, the ones that actually do all the CORS dance, don't require those headers to do CORS (cross-origin resource sharing). So, browsers don't even trigger anOPTIONSrequest before one with those headers.I think it would be useful for you to read the docs about CORS in MDN to understand how all that works: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS