我正在开发一个Flask服务器,用于在一些后端Python功能和Javascript客户端之间通过web进行通信。我试图利用Flask的session
变量在用户与应用程序交互的过程中存储特定于用户的数据。我已经删除了下面大部分特定于应用程序的代码,但我遇到的核心问题仍然存在。在
以下是我的(简化)烧瓶应用程序的代码:
import json
import os
from flask import Flask, jsonify, request, session
app = Flask(__name__)
app.secret_key = 'my_secret_key'
@app.route('/', methods=['GET'])
def run():
session['hello'] = 'world'
return jsonify(session['hello'])
@app.route('/update', methods=['POST'])
def update():
return jsonify(session['hello'])
if __name__ == '__main__':
app.run(host='0.0.0.0')
利用Postman,我可以向服务器发出GET请求并接收"world"
的预期输出。然后,我可以使用任意主体发出POST请求,并接收相同的预期输出"world"
(同样使用Postman)。在
使用Chrome时,我可以访问我的服务器IP并在页面上看到预期的输出"world"
。我还可以使用Javascript(在Chrome的控制台中)手动发出GET请求,并收到与预期相同的响应。但是,当试图使用Javascript向服务器发送POST请求时,我的问题就出现了;当试图发出这个请求时,服务器显示一个KeyError: 'hello'
。在
下面是我用来发出POST请求的Javascript:
^{pr2}$这里怎么了?为什么我可以用Postman发出GET/POST请求,但在使用Javascript发出相同的请求时会遇到错误?在
fetch
文档的caveats部分说明:建议使用AJAX与烧瓶视图交换信息。在
同时,在Flask应用程序的代码中,
session
对象是一个字典。现在,如果您使用它的键session['hello']
访问一个字典,如果这个键不存在,则会引发一个Keyerror
。为了避免这个错误,可以对字典使用get()
方法。在发生的情况是:
fetch
请求在Flask会话中找不到hello
键(或从Flask视图获取会话值)。在但这仍然会为会话
{ session_info: null }
提供一个null
值。为什么会这样?在当您向Flask服务器发送GET/POST请求时,会话将在Flask中初始化和查询。但是,当您发送Javascript
fetch
POST请求时,必须首先从Flask获取会话值,然后将其作为POST请求发送到Flask视图,该视图return
是会话信息。在在您的代码中,当POST请求从
^{pr2}$fetch
触发时,当我将有效负载数据发送到Flask时,它被正确地接收到,您可以使用Flask视图中的request.get_json()
进行检查:这将返回
{ payload: 'arbitrary_string', session_info: null }
。这还表明,fetch
没有收到会话信息,因为我们没有调用getfirst从Flask获取会话信息。在记住:Flask会话位于Flask服务器上。要通过Javascript发送/接收信息,必须单独调用,除非有存储会话cookie的规定。在
烧瓶视图将略有变化:
现在触发Javacript请求时,输出将是:
{ session_info: 'world' }
经过几个小时的测试,我设法解决了这个问题。虽然我认为@amanb的回答突出了这个问题,但我还是要回答我自己的问题,因为我发现的最终结果是一个更简单的解决方案。在
为了使POST请求返回预期值,我只需要在
fetch
主体中添加credentials: 'same-origin'
行。如下所示:根据Mozilla's Fetch usage guide
看来我看过了。更改凭据以允许客户端和服务器之间的cookie/会话通信解决了此问题。在
相关问题 更多 >
编程相关推荐