4.5 重定向和用户会话

前一版 hello.py 存在一个可用性问题。用户输入名字后提交表单,然后点击浏览器的刷新按钮,会看到一个莫名其妙的警告,要求在再次提交表单之前进行确认。之所以出现这种情况,是因为刷新页面时浏览器会重新发送之前发送过的请求。如果前一个请求是包含表单数据的 POST 请求,刷新页面后会再次提交表单。多数情况下,这并不是我们想执行的操作,因此浏览器才要求用户确认。

很多用户不理解浏览器发出的这个警告。鉴于此,最好别让 Web 应用把 POST 请求作为浏览器发送的最后一个请求。

这种需求的实现方式是,使用重定向作为 POST 请求的响应,而不是使用常规响应。重定向是一种特殊的响应,响应内容包含的是 URL,而不是 HTML 代码的字符串。浏览器收到这种响应时,会向重定向的 URL 发起 GET 请求,显示页面的内容。这个页面的加载可能 要多花几毫秒,因为要先把第二个请求发给服务器。除此之外,用户不会察觉到有什么不同。现在,前一个请求是 GET 请求,所以刷新命令能像预期的那样正常运作了。这个技巧称为 Post / 重定向 /Get 模式

但这种方法又会引起另一个问题。应用处理 POST 请求时,可以通过 form.name.data 获取用户输入的名字,然而一旦这个请求结束,数据也就不见了。因为这个 POST 请求使用重定向处理,所以应用需要保存输入的名字,这样重定向后的请求才能获得并使用这个名字, 从而构建真正的响应。

应用可以把数据存储在用户会话中,以便在请求之间“记住”数据。用户会话是一种私有存储,每个连接到服务器的客户端都可访问。我们在第 2 章介绍过用户会话,它是请求上下文中的变量,名为 session,像标准的 Python 字典一样操作。

  • 默认情况下,用户会话保存在客户端 cookie 中,使用前面设置的密钥加密签名。如果篡改了 cookie 的内容,签名就会失效,会话也将随之失效。

示例 4-5 是 index() 视图函数的新版本,实现了重定向和用户会话。

示例 4-5 hello.py:重定向和用户会话

from flask import Flask, render_template, session, redirect, url_for

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        session['name'] = form.name.data
        return redirect(url_for('index'))
    return render_template('index.html', form=form, name=session.get('name'))

应用的前一个版本在局部变量 name 中存储用户在表单中输入的名字。这个变量现在保存在用户会话中,即 session['name'],所以在两次请求之间能记住输入的值。

现在,包含有效表单数据的请求最后会使视图函数调用 redirect() 函数。这是 Flask 提供的辅助函数,用于生成 HTTP 重定向响应。redirect() 函数的参数是重定向的 URL,这里使用的重定向 URL 是应用的根 URL,因此重定向响应本可以写得更简单一些,写成 redirect('/'),不过这里却使用了 Flask 提供的 URL 生成函数 url_for()(参见第 3 章)。

url_for() 函数的第一个且唯一必须指定的参数是端点名,即路由的内部名称。默认情况下,路由的端点是相应视图函数的名称。在这个示例中,处理根 URL 的视图函数是 index(),因此传给 url_for() 函数的名字是 index。

最后一处改动位于 render_template() 函数中,现在我们使用 session.get('name') 直接从会话中读取 name 参数的值。与普通的字典一样,这里使用 get() 获取字典中键对应的值, 可以避免未找到键时抛出异常。如果指定的键不存在,则 get() 方法返回默认值 None。

使用这个版本的应用,在浏览器中刷新后看到的新页面就与预期一样了。

《基于Python的Web应用开发实战(第二版)》

转载于:https://www.cnblogs.com/hl001/p/10233799.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值