Flask 教程

Flask 静态文件

在 Web 开发中,静态文件指的是那些不需要经过 Python 代码处理,直接由服务器发送给浏览器的文件。最常见的包括:

  • CSS(样式表)
  • JavaScript(交互脚本)
  • Images(图片、图标)
  • Fonts(字体文件)

Flask 对静态文件提供了开箱即用的支持。以下是 Flask 处理静态文件的完整指南。


1. 默认配置与目录结构

默认情况下,Flask 会在你的应用根目录(即 app.py__init__.py 所在的目录)下寻找一个名为 static 的文件夹。

同时,Flask 会自动注册一个特殊的路由,URL 前缀为 /static,用来映射这个文件夹。

推荐的目录结构:

为了保持整洁,建议在 static 文件夹内部按文件类型创建子目录:

纯文本
plaintext
my_flask_project/
│
├── app.py                  # 你的 Flask 应用代码
├── templates/              # HTML 模板文件夹
│   └── index.html
│
└── static/                 # 📁 静态文件夹 (名字必须是 static)
    ├── css/                # 样式文件
    │   └── style.css
    ├── js/                 # 脚本文件
    │   └── main.js
    └── images/             # 图片文件
        └── logo.png

2. 在 HTML 模板中引用静态文件 ⭐ (最常用)

在 Jinja2 模板中引用静态文件时,永远不要硬编码 URL(例如直接写 /static/css/style.css)。
正确的做法是使用 url_for() 函数,端点名固定为 'static',并通过 filename 参数指定文件在 static 目录下的相对路径。

语法:

纯文本
plaintext
{{ url_for('static', filename='子目录/文件名') }}

完整 HTML 示例 (templates/index.html):

纯文本
plaintext
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Flask 静态文件示例</title>

    <!-- 引入 CSS -->
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>欢迎来到我的网站</h1>

    <!-- 引入图片 -->
    <img src="{{ url_for('static', filename='images/logo.png') }}" alt="网站 Logo" width="200">

    <!-- 引入 JavaScript (通常放在 body 底部) -->
    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

为什么必须用 url_for

  1. 灵活性:如果你以后修改了静态文件的 URL 前缀,所有模板会自动更新,无需逐个修改。
  2. 缓存控制:Flask 的某些扩展或配置可以通过 url_for 自动在 URL 后追加版本号(如 style.css?v=1.2)来解决浏览器缓存问题。

3. 在 Python 视图函数中引用

如果你需要在 Python 代码中生成静态文件的 URL(例如返回 JSON 数据给前端,或者在重定向时传递图片链接),同样使用 url_for

纯文本
plaintext
from flask import Flask, url_for, jsonify

app = Flask(__name__)

@app.route('/api/banner')
def get_banner():
    # 在 Python 代码中生成 URL
    image_url = url_for('static', filename='images/logo.png')

    return jsonify({
        "status": "success",
        "banner_image": image_url
    })

# 访问 /api/banner 会返回:
# {"banner_image": "/static/images/logo.png", "status": "success"}

4. 自定义静态文件路径 (进阶)

如果你不想使用默认的 static 文件夹,或者想修改 URL 前缀,可以在创建 Flask 实例时进行配置:

纯文本
plaintext
from flask import Flask

# 假设你的静态文件放在名为 'assets' 的文件夹里
# 并且你希望 URL 前缀变成 '/assets' 而不是 '/static'
app = Flask(__name__, 
            static_folder='assets',       # 物理文件夹名称
            static_url_path='/assets')    # URL 访问前缀

@app.route('/')
def index():
    # 此时引用方式也要相应改变
    return f'<img src="{url_for("static", filename="logo.png")}">' 
    # 注意:即使修改了 static_url_path,url_for 的端点名依然是 'static'

5. 蓝图 (Blueprint) 中的静态文件

在大型项目中,如果你使用蓝图来模块化代码,每个蓝图都可以拥有自己独立的静态文件夹

纯文本
plaintext
from flask import Blueprint, url_for

# 为 auth 蓝图指定独立的静态文件夹
auth_bp = Blueprint(
    'auth', 
    __name__,
    static_folder='static',         # 蓝图目录下的 static 文件夹
    static_url_path='/auth_static'  # 该蓝图静态文件的 URL 前缀
)

@auth_bp.route('/login')
def login():
    # 在蓝图模板或代码中引用该蓝图专属的静态文件
    img_url = url_for('auth.static', filename='login_bg.jpg')
    return f'<img src="{img_url}">'

注:主应用的静态文件端点依然是 'static',蓝图的静态文件端点是 '<蓝图名>.static'


⚠️ 生产环境的重要警告

Flask 内置的开发服务器处理静态文件的效率非常低! 它每次请求都会经过 Python 进程,不适合高并发场景。

当你将项目部署到生产环境时,绝对不要让 Flask 去处理静态文件。正确的做法是:

  1. 使用 Nginx / Apache 托管:配置 Web 服务器直接拦截 /static/ 开头的请求,直接从磁盘读取文件返回,不经过 Flask。
  2. 使用 CDN (内容分发网络):将静态文件上传到阿里云 OSS、AWS S3 或 Cloudflare 等 CDN 服务,加快全球访问速度。

Nginx 配置示例 (仅供参考):

纯文本
plaintext
server {
    listen 80;
    server_name example.com;

    # 1. Nginx 直接处理静态文件
    location /static/ {
        alias /path/to/your/project/static/;
        expires 30d; # 开启浏览器缓存
    }

    # 2. 其他请求代理给 Flask (Gunicorn/uWSGI)
    location / {
        proxy_pass http://127.0.0.1:8000;
    }
}

📝 总结

场景做法
存放位置项目根目录下的 static/ 文件夹
模板中引用{{ url_for('static', filename='css/style.css') }}
Python 中引用url_for('static', filename='images/logo.png')
生产环境交给 Nginx 或 CDN 处理,不要让 Flask 处理

掌握了静态文件,你的网页就可以变得美观且具备交互能力了。接下来,你想学习如何渲染 Jinja2 模板(将 Python 数据动态填入 HTML),还是学习如何连接数据库

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注