静态文件

Flask 默认从应用目录下的 static/ 文件夹提供 CSS、JavaScript、图片等静态资源,URL 前缀为 /static/

目录结构

app/
  static/
    css/style.css
    js/main.js
    img/logo.png
  templates/
    index.html
  __init__.py

在模板中引用

始终使用 url_for('static', filename=...) 生成静态文件 URL,而不是硬编码路径——这样修改静态目录或加 CDN 前缀时模板无需改动:

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/main.js') }}" defer></script>
<img src="{{ url_for('static', filename='img/logo.png') }}" alt="Logo">

自定义静态目录与 URL 前缀

app = Flask(
    __name__,
    static_folder="assets",       # 磁盘目录改为 assets/
    static_url_path="/static",    # URL 前缀仍是 /static
)

蓝图也可以携带自己的静态目录,实现模块级资源隔离:

bp = Blueprint("blog", __name__, static_folder="static", static_url_path="/blog-static")

缓存控制

开发时浏览器缓存常导致改了 CSS 看不到效果。可设置静态文件的缓存时长:

# 开发环境:禁用缓存
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0

# 生产环境:长缓存(配合文件名指纹)
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 31536000

用户上传文件与 send_from_directory

用户上传的文件不应放进 static/(避免被任意访问),用受控视图提供下载:

from flask import send_from_directory

@app.get("/uploads/<path:filename>")
def uploaded_file(filename):
    # send_from_directory 会做路径安全检查,防止目录穿越
    return send_from_directory(app.config["UPLOAD_FOLDER"], filename)

生产环境最佳实践

  • 不要用 Flask 进程直接服务大量静态请求:让 Nginx/Caddy 等反向代理直接发送 static/ 目录,或使用 CDN。
  • 指纹化(cache busting):前端构建工具(Vite/Webpack)会在文件名中加入哈希(如 app.3f8a2c.js),可放心配置一年长缓存。
  • 压缩:在代理层启用 gzip/brotli,而不是在 Flask 中处理。

Nginx 示例:

location /static/ {
    alias /srv/myapp/app/static/;
    expires 1y;
    add_header Cache-Control "public, immutable";
}