在 Web 开发中,静态文件指的是那些不需要经过 Python 代码处理,直接由服务器发送给浏览器的文件。最常见的包括:
- CSS(样式表)
- JavaScript(交互脚本)
- Images(图片、图标)
- Fonts(字体文件)
Flask 对静态文件提供了开箱即用的支持。以下是 Flask 处理静态文件的完整指南。
1. 默认配置与目录结构
默认情况下,Flask 会在你的应用根目录(即 app.py 或 __init__.py 所在的目录)下寻找一个名为 static 的文件夹。
同时,Flask 会自动注册一个特殊的路由,URL 前缀为 /static,用来映射这个文件夹。
推荐的目录结构:
为了保持整洁,建议在 static 文件夹内部按文件类型创建子目录:
my_flask_project/
│
├── app.py # 你的 Flask 应用代码
├── templates/ # HTML 模板文件夹
│ └── index.html
│
└── static/ # 📁 静态文件夹 (名字必须是 static)
├── css/ # 样式文件
│ └── style.css
├── js/ # 脚本文件
│ └── main.js
└── images/ # 图片文件
└── logo.png2. 在 HTML 模板中引用静态文件 ⭐ (最常用)
在 Jinja2 模板中引用静态文件时,永远不要硬编码 URL(例如直接写 /static/css/style.css)。
正确的做法是使用 url_for() 函数,端点名固定为 'static',并通过 filename 参数指定文件在 static 目录下的相对路径。
语法:
{{ url_for('static', filename='子目录/文件名') }}完整 HTML 示例 (templates/index.html):
<!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?
- 灵活性:如果你以后修改了静态文件的 URL 前缀,所有模板会自动更新,无需逐个修改。
- 缓存控制:Flask 的某些扩展或配置可以通过
url_for自动在 URL 后追加版本号(如style.css?v=1.2)来解决浏览器缓存问题。
3. 在 Python 视图函数中引用
如果你需要在 Python 代码中生成静态文件的 URL(例如返回 JSON 数据给前端,或者在重定向时传递图片链接),同样使用 url_for:
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 实例时进行配置:
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) 中的静态文件
在大型项目中,如果你使用蓝图来模块化代码,每个蓝图都可以拥有自己独立的静态文件夹。
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 去处理静态文件。正确的做法是:
- 使用 Nginx / Apache 托管:配置 Web 服务器直接拦截
/static/开头的请求,直接从磁盘读取文件返回,不经过 Flask。 - 使用 CDN (内容分发网络):将静态文件上传到阿里云 OSS、AWS S3 或 Cloudflare 等 CDN 服务,加快全球访问速度。
Nginx 配置示例 (仅供参考):
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),还是学习如何连接数据库?