Tenho um aplicativo React que estou tentando servir estaticamente do FastAPI. Tenho todos os meus artefatos de build do React na minha static
pasta. Então, meu aplicativo FastAPI se parece com isso:
static/
assets/
index-lATvXaZG.js
index.html
app.py
Em app.py , tenho:
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="react")
@app.get("")
@app.get("/")
@app.get("/index.html")
def serve_index():
return FileResponse("static/index.html")
No entanto, quando index.html
é carregado, o cliente compreensivelmente faz uma solicitação GET para /assets/index-lATvXaZG.js
. Claro, FastAPI não consegue encontrar isso.
Existe alguma configuração que eu possa colocar no meu aplicativo React (ou, talvez, na minha configuração FastAPI) para alinhar os caminhos?
Devo começar recomendando fortemente que você dê uma olhada nesta resposta e nesta resposta , pois a resposta postada aqui é essencialmente baseada no que está descrito nessas respostas.
Opção 1
O problema deve ser facilmente resolvido usando corretamente a
StaticFiles
instância para tais propósitos. Isso significa que você deve definir ohtml
sinalizador paraTrue
e servir os arquivos estáticos em/
route. Dessa forma, você pode acessar oindex.html
simplesmente digitando na barra de endereços do navegador, por exemplo,http://127.0.0.1:8000/
ouhttp://localhost:8000/
. Portanto, quaisquer referências a/assets/whatever
devem funcionar perfeitamente.Exemplo
Mantenha a estrutura dos seus arquivos como está:
Opção 2
Se você quiser manter sua implementação atual (o que eu não recomendaria) — ou seja, montar a
StaticFiles
instância no/static
caminho, ou seja,app.mount("/static", StaticFiles(directory="static"), name="static")
e manter ohtml
sinalizador definido comoFalse
(que é a configuração padrão) — você pode simplesmente adicionar a seguinte linha no topo de cada arquivo HTML nostatic
diretório, ou seja:Dessa forma, o prefixo
static/
deve ser adicionado automaticamente a qualquer referência feita dentro do(s) arquivo(s) HTML e resolver o problema (astatic/
ausência do início da referência é essencialmente o motivo para não encontrar oassets
, já que você os serve na/static
rota—app.mount("/static",...
).Opção 3
Alternativamente , se você não quiser adicionar
<base href="static/">
a cada arquivo, você pode ter um personalizado404
exception_handler
, como demonstrado aqui , e dentro dele obter o caminho da URL doRequest
objeto, como mostrado aqui , e então anexarstatic/
à frente do caminho e retornar umFileResponse
(se o arquivo existir). Exemplo:Em vez do costume
404
exception_handler
, pode-se usar um endpoint para servir tais arquivos de ativos (semelhante a este ), capturando o caminho da URL, como explicado aqui , e anexando-ostatic/assets/
à frente dele. Portanto, quaisquer arquivos que estejam sob oassets/
diretório, comoassets/index.js
ouassets/images/img.png
, seriam servidos com sucesso.Novamente, essa é uma abordagem que eu realmente não recomendaria seguir e com a qual se deve ter muito cuidado, pois alguém pode tentar tirar vantagem dela de forma maliciosa e tentar acessar arquivos provavelmente restritos aos quais não está autorizado. É por isso que
os.path.join('static/', ...
é usado nos exemplos acima, para mitigar esses riscos e procurar apenas arquivos nostatic/
diretório.A escolha da Opção 1 descrita anteriormente deve ser a abordagem preferida para tais propósitos.
Ao criar seu aplicativo React, especifique a página inicial em package.json ou defina o PUBLIC_URL durante a criação:
"página inicial": "/estático" npm executar compilação
app.mount("/static", StaticFiles(diretório="static", html=True), nome="static")
@app.get("/") def serve_index():`insira o código aquiinsira o código aqui return FileResponse("static/index.html")
Isso deve servir adequadamente tanto index.html quanto ativos estáticos em /static. Tente isso e me avise se tiver algum problema