Почему в FastAPI при редиректе пропадает заголовок?

Не получается принять отправленный параметр в head:

from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
import uvicorn

app = FastAPI()

@app.get("/create_head")
def create_head():
    redirect = RedirectResponse("/read_head", headers={'secret': '123459'})
    print('redirect:', redirect)
    print('redirect.headers', redirect.headers)
    return redirect

@app.get("/read_head")
def read_head(request: Request):
    secret = request.headers.get('secret')
    print('secret:', secret)
    return secret

if __name__ == '__main__':
    uvicorn.run(app)

Консоль показывает, что установлено, но на принятии - исчезает:

redirect: <starlette.responses.RedirectResponse object at 0x000001BA06385390>
redirect.headers MutableHeaders({'secret': '123459', 'content-length': '0', 'location': '/read_head'})
INFO:     127.0.0.1:64147 - "GET /create_head HTTP/1.1" 307 Temporary Redirect
secret: None
INFO:     127.0.0.1:64147 - "GET /read_head HTTP/1.1" 200 OK

Что не так я сделал? Или есть какой-то подводный камень?

UPD - Добавил как JSONResponse отправлляет кастомный заголовок:

введите сюда описание изображения

UPD2 - Попытки через CORSMiddleware:

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["GET"],
    allow_headers=["*"],
)

Ответы (1 шт):

Автор решения: Alexey Ten

Никуда он не пропадает. Изучите как работает протокол HTTP.

Ваш заголовок secret честно ушёл в виде ответа к браузеру (и его даже можно будет увидеть в инструментах разработчика).

Но браузеру этот заголовок совершенно незнаком и он его просто проигнорирует. И сделает то что его попросили, перейдёт но новой ссылке /read_head, отправив стандартные заголовки (Host, User-Agent, Cookie и т.п.).

Повторюсь ещё раз — нет никакого способа заставить браузер отправить нестандартные заголовки в обычном запросе.

Либо используйте куки, либо делайте запросы самостоятельно из JS с помощью fetch.

UPD: Пьеса «Общение браузера и сервера»

  • Браузер: Эй, сервер, дай мне ресурс /create_head.
    GET /create_head HTTP/1.1
    Host: server
    
  • Сервер: Ага, сходи на /read_head и вот тебе ещё заодно заголовок secret: 123459
    HTTP/1.1 307 Temporary Redirect
    Location: /read_head
    secret: 123459
    
  • Браузер: ага, надо пойти на /read_head, а что это за secret? Не знаю такого заголовка, игнорируем. Эй, сервер, дай мне страничку /read_head
    GET /read_head HTTP/1.1
    Host: server
    
  • Сервер: хм, никакого заголовка secret. Ну ладно, забирай страничку
    HTTP/1.1 200 OK
    [...]
    
→ Ссылка