【发布时间】:2018-01-23 02:32:15
【问题描述】:
应用程序设置:使用默认会话在 eventlet WSGI 中运行的 Flask
在客户端,我使用 jQuery 从异步事件处理程序中向服务器发送 POST 请求:
function set_option(option, value) {
$.post('/api/options/' + option, {'value': value});
}
$('.option').change(function() {
var element_id = $(this).prop('id');
var value = $(this).val();
set_option(element_id, value);
});
在服务器端,我将选项及其值添加到 Flask 会话中:
from flask import Flask, request, session
app = Flask(__name__)
[...]
@app.route('/api/options/<option>', methods=['POST'])
def set_option(option=None):
if request.method == 'POST' and option is not None:
option_value = request.form.get('value')
if option_value is not None:
session[option] = option_value
上述客户端事件处理程序有时可以在给定时刻内多次调用。这似乎会导致 Flask 会话 cookie 出现争用情况。例如,如果事件处理程序因对不同元素的两次强制 .change() 调用而被触发两次,则会话最终只会根据最后一个 POST 请求进行修改。
假设有两个元素被更改为以下值:
option_one='1234' and option_two='5678'
Flask 会话已经包含以下内容:
{'option_one': '0', 'option_two': '0'}
对于每个选项,分别向 Flask 服务器发送两个单独的请求。第一个请求将 Flask 会话设置为:
{'option_one': '1234', 'option_two': '0'}
第二个请求将 Flask 会话设置为:
{'option_one':'0', 'option_two': '5678'}
第二个请求的会话最终替换了第一个请求的会话,从而消除了为 option_one 存储的所需值。
考虑到这一点,如果在每次调用之间的时间更长的情况下调用事件处理程序,会话 cookie 似乎会适当更新。
当请求在几百毫秒内发出时,Flask 的这种行为及其会话/cookie 管理是否正常?
服务器端会话管理会是一种解决方案吗?
【问题讨论】:
-
嗯,是的,当然有竞争条件。如果您的请求 A 和 B 都具有相同的会话 cookie 被发送到 Flask,Flask 无法知道有两个单独的请求具有相同的会话 cookie,您希望连续更新这些请求。相反,Flask 将使用请求 A 更新会话 cookie,并且单独使用请求 B 更新会话 cookie,并且浏览器将获取最后到达的任何响应的 cookie 值。
-
解决方案是不要将此信息存储在 cookie 中。仅在会话中存储一个标识符,并根据该标识符操作服务器端数据存储,并在那里序列化您的操作,或者确保在那里处理冲突。
-
@MartijnPieters 谢谢...我对 cookie 的工作原理不是很熟悉,但这证实了我最初的想法。
-
这可能就是我最终会做的事情。再次感谢!
标签: python asynchronous flask session-cookies