分析了您提供的 Flask 路由代码,以下是针对各功能模块的优化建议及实现方案,涵盖错误处理、模板渲染、表单验证和请求处理等核心场景。
当前 abort(404)
和自定义错误处理较为基础,建议升级为标准化错误响应:
# 标准化错误响应结构
class APIError(Exception):
def __init__(self, message, status_code=400, error_code=1000):
super().__init__()
self.message = message
self.status_code = status_code
self.error_code = error_code
# 全局错误处理
@app.errorhandler(APIError)
def handle_api_error(error):
response = jsonify({
'success': False,
'message': error.message,
'error_code': error.error_code
})
response.status_code = error.status_code
return response
@app.errorhandler(404)
def handle_404(error):
# 区分API请求和页面请求
if request.accept_mimetypes.accept_json and \
not request.accept_mimetypes.accept_html:
return jsonify({
'success': False,
'message': 'Resource not found',
'error_code': 404
}), 404
return render_template('404.html'), 404
# 优化后的abort路由
@app.route('/abort/')
def test_abort(id):
if id != 1:
# 抛出标准化API错误
raise APIError('ID must be 1', status_code=400, error_code=2001)
return f'传入值正确:id={id}'
/info
路由可增强数据获取逻辑和模板渲染:
# 优化数据库查询逻辑
def get_user_movies(user_id):
"""从数据库获取用户相关电影"""
try:
# 假设Movie是数据库模型
return Movie.query.filter_by(user_id=user_id).all()
except Exception as e:
app.logger.error(f"Database query error: {e}")
raise APIError('Failed to fetch movies', 500, 3001)
@app.route("/info")
def info():
try:
# 假设user_id从会话中获取
user_id = session.get('user_id')
if not user_id:
raise APIError('User not logged in', 401, 4001)
# 从数据库获取用户信息(假设User是数据库模型)
user = User.query.get(user_id)
if not user:
raise APIError('User not found', 404, 4002)
# 获取电影数据
movies = get_user_movies(user_id)
return render_template(
"user_info.html",
user=user,
movies=movies,
page_title="用户信息与电影列表"
)
except APIError as e:
# 处理API错误
if request.accept_mimetypes.accept_json:
return jsonify({
'success': False,
'message': e.message,
'error_code': e.error_code
}), e.status_code
flash(e.message, 'error')
return redirect(url_for('index'))
except Exception as e:
app.logger.error(f"Unexpected error: {e}", exc_info=True)
flash('服务器错误,请稍后再试', 'error')
return redirect(url_for('index'))
根路由的表单处理可增加数据验证和重定向逻辑:
# 表单验证函数
def validate_username(username):
"""验证用户名格式"""
if not username:
return False, "用户名不能为空"
if len(username) < 3 or len(username) > 20:
return False, "用户名长度需在3-20字符之间"
if not re.match(r'^[a-zA-Z0-9_]+$', username):
return False, "用户名只能包含字母、数字和下划线"
return True, ""
@app.route("/", methods=["GET", "POST"])
def login():
if request.method == "POST":
username = request.form.get("username")
password = request.form.get("password") # 假设添加密码字段
# 验证用户名
valid, message = validate_username(username)
if not valid:
flash(message, 'error')
return render_template("login.html", username=username) # 保留已输入的用户名
# 验证密码(假设存在)
if not password:
flash("密码不能为空", 'error')
return render_template("login.html", username=username)
# 模拟用户验证(实际应查询数据库)
user = User.query.filter_by(username=username).first()
if not user or not user.verify_password(password):
flash("用户名或密码错误", 'error')
return render_template("login.html", username=username)
# 登录成功,设置会话
session['user_id'] = user.id
session['username'] = user.username
session.permanent = True # 设置持久会话
# 重定向时传递next参数(如果有)
next_url = request.args.get('next')
if next_url and is_safe_url(next_url):
return redirect(next_url)
flash("登录成功", 'success')
return redirect(url_for("dashboard")) # 重定向到仪表盘页面
return render_template("login.html")
/test
路由可增强请求数据处理和响应格式:
@app.route("/test", methods=["GET", "POST"])
def handle_request():
data = {}
# 处理GET请求参数
if request.method == "GET":
test1 = request.args.get("test1")
if test1:
data['test1'] = test1
app.logger.info(f"Received GET parameter: test1={test1}")
else:
data['warning'] = "test1 parameter is missing"
# 处理POST请求数据
elif request.method == "POST":
# 处理表单数据
test2 = request.form.get("test2")
if test2:
data['test2'] = test2
app.logger.info(f"Received POST form data: test2={test2}")
# 处理JSON数据(如果存在)
if request.is_json:
try:
json_data = request.json
data['json_data'] = json_data
app.logger.info(f"Received JSON data: {json_data}")
except Exception as e:
app.logger.error(f"Invalid JSON: {e}")
data['error'] = "Invalid JSON format"
# 添加请求元数据
data['request_method'] = request.method
data['timestamp'] = datetime.datetime.now().isoformat()
data['success'] = True
return jsonify(data), 200
1、添加 URL 安全验证:
from werkzeug.urls import url_parse
def is_safe_url(target):
"""验证重定向URL是否安全"""
ref_url = url_parse(request.host_url)
test_url = url_parse(target)
return test_url.scheme in ('http', 'https') and \
ref_url.netloc == test_url.netloc
2、CSRF 保护(使用 Flask-WTF):
from flask_wtf.csrf import CSRFProtect
csrf = CSRFProtect(app)
# 在表单模板中添加:
#
your_app/
├── __init__.py
├── models.py # 数据库模型
├── routes/
│ ├── auth.py # 认证相关路由
│ ├── api.py # API接口路由
│ ├── pages.py # 页面路由
│ └── errors.py # 错误处理
├── templates/
│ ├── base.html # 基础模板
│ ├── login.html # 登录页面
│ ├── user_info.html # 用户信息页面
│ ├── 404.html # 404错误页面
│ └── result.html # 结果页面
├── static/ # 静态资源
├── utils/ # 工具函数
└── config.py # 配置文件
通过以上优化,您的 Flask 应用将具备更完善的错误处理机制、更安全的表单验证、更灵活的请求响应处理,同时代码结构也更加清晰和可维护。建议根据实际业务需求逐步集成这些优化点,并配合单元测试确保功能稳定性。