You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用FastAPI和Jinja2在HTML页面中显示上传的图片?

问题:FastAPI + Jinja2 上传图片后无法通过img标签显示

我用FastAPI和Jinja2搭建了一个图片上传页面,上传完成后通过图片名称链接打开另一个页面展示图片。目前上传和链接功能正常,但img标签无法显示图片,求解决办法。

现有代码

main.py

from fastapi import FastAPI, File, UploadFile, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles 
from fastapi.templating import Jinja2Templates

app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")

""" upload file and save it to local """ 
@app.post("/upload-file")
async def upload_file(file: UploadFile = File(...)):
    with open(file.filename, "wb") as f:
        f.write(file.file.read())
    return {"filename": file.filename}

''' create html page to show uploaded file '''
@app.get("/")
async def root():
    html_content = """
    <html>
        <head>
            <title>Upload File</title>
        </head>
        <body>
            <h1>Upload File</h1>
            <form action="/upload-file/" method="post" enctype="multipart/form-data">
                <input type="file" name="file" />
                <input type="submit" />
            </form>
        </body>
    </html>
    """
    return HTMLResponse(content=html_content)


templates = Jinja2Templates(directory="templates")

@app.get("/{filename}", response_class=HTMLResponse)
async def read_item(request: Request, filename: str):
    return templates.TemplateResponse("template.html", {"request": request,"filename": filename})

template.html

<!DOCTYPE html>
<html>
<head>
    <title>HTML img Tag</title>
</head>

<body>
    <img src= "{{./filename}} " alt="uploaded image" width="400" height="400">
</body>
</html> 

我也接受更优、更简便的实现方式,谢谢。


解决办法

问题根源

  1. 文件存储路径错误:上传的图片直接存在项目根目录,但FastAPI仅配置/static路径对应本地static目录的静态文件,根目录文件无法被静态服务访问。
  2. img标签语法错误:Jinja2模板中{{./filename}}的写法不符合语法,无法生成正确的静态文件URL。

修改步骤

1. 修正文件存储路径

修改/upload-file接口,将文件保存到static目录下(若static目录不存在需手动创建):

@app.post("/upload-file")
async def upload_file(file: UploadFile = File(...)):
    # 拼接static目录的文件路径
    file_path = f"static/{file.filename}"
    with open(file_path, "wb") as f:
        f.write(file.file.read())
    return {"filename": file.filename}

2. 修正模板的img标签路径

在template.html中使用FastAPI提供的url_for函数生成正确的静态文件URL:

<!DOCTYPE html>
<html>
<head>
    <title>HTML img Tag</title>
</head>

<body>
    <img src="{{ url_for('static', path=filename) }}" alt="uploaded image" width="400" height="400">
</body>
</html> 

优化建议(可选)

  • 处理文件重名:给上传文件添加随机前缀或时间戳,避免同名文件被覆盖:
    import uuid
    from pathlib import Path
    
    @app.post("/upload-file")
    async def upload_file(file: UploadFile = File(...)):
        # 生成唯一文件名
        unique_filename = f"{uuid.uuid4().hex}_{file.filename}"
        file_path = Path("static") / unique_filename
        with open(file_path, "wb") as f:
            f.write(file.file.read())
        return {"filename": unique_filename}
    
  • 上传页面改用模板:将首页HTML内容移至templates目录下的upload.html,用TemplateResponse返回,更贴合Jinja2使用习惯:
    @app.get("/", response_class=HTMLResponse)
    async def root(request: Request):
        return templates.TemplateResponse("upload.html", {"request": request})
    
    upload.html内容:
    <html>
        <head>
            <title>Upload File</title>
        </head>
        <body>
            <h1>Upload File</h1>
            <form action="/upload-file/" method="post" enctype="multipart/form-data">
                <input type="file" name="file" />
                <input type="submit" />
            </form>
        </body>
    </html>
    

内容的提问来源于stack exchange,提问作者Aboude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:48:24