基于蓝图/配置优雅实现文件保存与回传的方案咨询
嘿,这个需求其实挺常见的,结合Flask蓝图和配置来实现的话,咱们可以按以下步骤来,既符合最佳实践又足够优雅:
1. 先完善配置,确保路径安全
首先你的config.py可以优化一下,用绝对路径定义上传文件夹,同时加上文件大小限制,避免潜在问题:
import os class Config(object): # 用绝对路径指定上传文件夹,避免相对路径带来的运行目录问题 UPLOAD_FOLDER = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'uploads') # 限制上传文件最大为16MB,可根据需求调整 MAX_CONTENT_LENGTH = 16 * 1024 * 1024
2. 初始化App时加载配置并确保文件夹存在
在application.py里,我们需要加载配置、注册蓝图,同时自动创建上传文件夹(避免保存文件时报错):
from flask import Flask from app.api_routes import api_bp from app.main_routes import main_bp import os app = Flask(__name__) # 加载配置类 app.config.from_object('config.Config') # 自动创建上传文件夹(不存在则创建) os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 注册蓝图,给API蓝图加前缀/api,方便区分路由 app.register_blueprint(api_bp, url_prefix='/api') app.register_blueprint(main_bp)
3. 在蓝图中实现上传与文件回传逻辑
首先确保你的API蓝图已正确创建(app/api_routes/__init__.py):
from flask import Blueprint # 创建API蓝图 api_bp = Blueprint('api', __name__) # 导入路由,放在蓝图创建之后 from app.api_routes import routes
然后在app/api_routes/routes.py里编写上传和文件访问的核心逻辑:
from flask import request, send_from_directory, jsonify from app.api_routes import api_bp from werkzeug.utils import secure_filename import os from application import app # 也可以用from flask import current_app来动态获取配置 # 处理文件上传的路由 @api_bp.route('/upload', methods=['POST']) def upload_file(): # 检查请求中是否包含文件 if 'file' not in request.files: return jsonify({'error': '请求中没有文件部分'}), 400 file = request.files['file'] # 检查用户是否选择了文件 if file.filename == '': return jsonify({'error': '未选择上传文件'}), 400 if file: # 安全处理文件名,防止路径遍历攻击 safe_filename = secure_filename(file.filename) # 拼接完整的保存路径 save_path = os.path.join(app.config['UPLOAD_FOLDER'], safe_filename) # 保存文件 file.save(save_path) # 生成客户端可直接访问的文件URL file_url = f"{request.host_url}api/uploads/{safe_filename}" # 返回成功信息和文件URL return jsonify({ 'message': '文件上传成功', 'file_url': file_url, 'filename': safe_filename }), 201 # 提供上传文件的访问/下载路由 @api_bp.route('/uploads/<filename>') def serve_uploaded_file(filename): # 用Flask内置的send_from_directory安全返回文件,自动处理MIME类型 return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
为什么这样实现?
- 安全优先:用
secure_filename过滤文件名避免恶意路径遍历,send_from_directory确保只返回指定文件夹内的文件 - 配置驱动:所有路径依赖配置类,后续修改上传路径只需改
config.py,无需改动业务代码 - 蓝图解耦:上传逻辑完全封装在API蓝图中,和主路由互不干扰,便于维护和扩展
- 灵活扩展:如果需要给文件访问加权限验证,直接在
serve_uploaded_file路由里添加逻辑即可
测试一下
你可以用curl或者Postman测试上传:
curl -X POST -F "file=@10_0_0.jpg" http://localhost:5000/api/upload
返回的JSON里会包含file_url,直接访问这个URL就能下载到你上传的文件啦~
内容的提问来源于stack exchange,提问作者Joost
相关产品推荐
相关产品推荐

