Flask - 重定向与错误处理
Flask – 重定向与错误处理
Section titled “Flask – 重定向与错误处理”重定向 (Redirect) 是 Web 应用的基本组成部分。它们用于将用户的浏览器从一个 URL 发送到另一个 URL。常见用例包括:
- 表单成功提交后重定向(例如,从登录表单重定向到用户仪表板)。
- 操作完成后重定向(例如,删除项目后重定向回列表视图)。
- 将用户从旧 URL 指向新 URL。
- 强制使用规范 URL (Canonical URL)(例如,添加或移除末尾斜杠)。
Flask 提供了 redirect() 函数来生成重定向响应 (redirect response)。
The redirect() Function
Section titled “The redirect() Function”from flask import redirect, url_for
# 在视图函数内部:def process_action(): # ... 执行某些操作 ... # 重定向到 'show_results' endpoint return redirect(url_for('show_results'))参数:
location: 要重定向用户的 URL。强烈建议使用url_for()生成此 URL,而不是硬编码路径。code=302: 重定向的 HTTP 状态码。默认为302 Found(临时重定向)。Response=None: 可选的自定义 Response 类。
常见的重定向状态码:
301 Moved Permanently(永久移动): 当资源已永久移动到新位置时使用。搜索引擎通常会更新其链接。302 Found(已找到): 默认值。表示临时重定向。客户端在将来的请求中应继续使用原始 URL。303 See Other(查看其他位置): 通常在 POST 请求后使用,通过 GET 请求将客户端重定向到不同的 URL(通常是成功页面)。有助于防止用户刷新时意外重复提交。307 Temporary Redirect(临时重定向): 类似于 302,但指示客户端对新请求使用相同的 HTTP 方法(例如,如果原始请求是 POST,则重定向请求也应是 POST)。
示例: 登录尝试后的重定向
from flask import Flask, redirect, url_for, render_template, request, flash
app = Flask(__name__)# 消息闪现所需app.secret_key = 'redirect-example-secret'
@app.route('/login-redir')def login_form(): # 渲染 templates/login_redir.html return render_template('login_redir.html')
@app.route('/process-login-redir', methods=['POST'])def process_login(): # 模拟检查凭据 if request.form.get('username') == 'admin': flash('Login successful!', 'success') # 使用 url_for() 重定向到成功页 return redirect(url_for('success_page')) else: flash('Invalid username.', 'error') # 登录失败,重定向回登录表单 return redirect(url_for('login_form'))
@app.route('/login-success')def success_page(): return 'Logged in successfully!'
# 假定的模板: templates/login_redir.html# <!DOCTYPE html><html><head><title>Login</title></head><body># {% with messages = get_flashed_messages(with_categories=true) %}# {% if messages %}# {% for category, message in messages %}<p class="{{category}}">{{ message }}</p>{% endfor %}# {% endif %}# {% endwith %}# <form method="post" action="{{ url_for('process_login') }}"># Username: <input type="text" name="username"><br># <input type="submit" value="Login"># </form></body></html>
if __name__ == '__main__': app.run(debug=True, port=5008)使用 abort() 处理错误
Section titled “使用 abort() 处理错误”有时,由于错误条件(例如,找不到资源、用户未授权、输入无效),请求 (request) 的处理无法正常继续。在这种情况下,您应该发出适当的 HTTP 错误状态信号。Flask 为此提供了 abort() 函数。
The abort() Function
Section titled “The abort() Function”abort() 立即停止当前视图函数 (view function) 的执行,并针对给定的状态码抛出一个 HTTPException。Flask 会捕获此异常,并将相应的错误页面返回给客户端。
from flask import abort, session
@app.route('/product/<int:product_id>')def get_product(product_id): product = find_product_in_db(product_id) # 假设此函数存在 if product is None: # 未找到产品,使用 404 错误终止 abort(404) return render_template('product_details.html', product=product)
@app.route('/admin/config')def admin_config(): if not session.get('is_admin'): # 用户未授权,使用 403 错误终止 abort(403) return 'Admin Configuration Page'abort() 的常见错误状态码:
400 Bad Request(错误请求):无效的请求语法或参数。401 Unauthorized(未经授权):需要认证,但缺失或失败。403 Forbidden(禁止访问):已认证用户没有权限访问该资源。404 Not Found(未找到):请求的资源无法找到。405 Method Not Allowed(方法不允许):此 URL 不支持使用的 HTTP 方法(例如 POST)。410 Gone(已失效):资源曾经存在,但已永久不可用。500 Internal Server Error(内部服务器错误):表示意料之外的服务器错误的通用代码。
您还可以向 abort() 传递 description 参数:
abort(400, description="Missing 'user_id' parameter in request.")使用 @errorhandler 自定义错误页面
Section titled “使用 @errorhandler 自定义错误页面”您可以使用 @errorhandler() 装饰器 (decorator) 为特定的 HTTP 错误码创建自定义的、用户友好的模板 (template),而不是显示 Flask 的默认错误页面。
from flask import render_template
@app.errorhandler(404)def handle_not_found_error(error): # 如果需要,记录错误日志: app.logger.warning(f'页面未找到: {request.path}') # 'error' 参数包含有关异常的信息 return render_template('errors/404.html'), 404 # 返回模板和状态码
@app.errorhandler(403)def handle_forbidden_error(error): return render_template('errors/403.html'), 403
@app.errorhandler(500)def handle_internal_error(error): # 如果适用,在此处回滚数据库会话通常是好的做法 # db.session.rollback() app.logger.error(f'Server Error: {error}', exc_info=True) return render_template('errors/500.html'), 500
# --- 假定模板 ---# templates/errors/404.html: "Sorry, the page you requested was not found."# templates/errors/403.html: "Sorry, you do not have permission to access this page."# templates/errors/500.html: "Sorry, something went wrong on our end. Please try again later."# ------------------------当发生与注册的处理程序 (handler) 对应的错误时(无论是通过 abort() 还是导致 500 错误的未处理异常 exception),Flask 将执行关联的错误处理函数,而不是其默认行为。