【问题标题】:Flask Session does not hold any value between RequestsFlask Session 在请求之间不保存任何值
【发布时间】:2020-07-01 03:52:22
【问题描述】:

我是一名新手 Web 开发人员,我正在尝试实现一个 Flask + React 应用程序。 在 React 中,我有一个要求输入用户 ID 和密码的表单。用户输入所需数据后,React (Axios) 使用函数updateDoneStatus 将其发送到我的后端,如图所示(它调用getName 来提取派生数据):

 getName = () => {
     axios.get('http://127.0.0.1:5000/data')
      .then(res => {
            const name = res.data['name'];
            this.setState({name: name})
      }).catch(e => {
        console.log(e);
    });

 updateDoneStatus = () => { 
     this.setState({done: true})

     axios.post("http://127.0.0.1:5000/login",{
          data: {
              id: this.state.id,
              pw: this.state.pw
          }
      }).catch(e => {
         console.log(e);
      }).then(this.getName)};

当用户完成表单时,我的后端设法获取发送的数据并开始网络抓取,如下所示:

from flask import *
from flask_session.__init__ import Session
import requests
from bs4 import BeautifulSoup
from flask_cors import CORS
import re

app = Flask(__name__)
CORS(app)
app.config['SECRET_KEY'] = 'super secret key'
userID = ""
userPW = ""

@app.route("/login", methods=['POST'])
def getData():
    nameArr = []
    if request.get_json() != None:
        data = request.get_json()
        userID = str(data["data"]["id"])
        userPW = str(data["data"]["pw"])

        login_data = {
        'userid' :  userID,
        'pwd' : userPW,
        'Submit' : 'Sign In'
        }

        with requests.Session() as s:
            url = 'SOME URL'
            r = s.post(url,data = login_data)
            newUrl = 'SOME OTHER URL'
            a = s.get(newUrl)
            src = a.content
            soup = BeautifulSoup(src,features="html.parser")
            text = soup.get_text()
            nameArr = re.findall("some regex",re.findall("some regex",text)[0])

            session.permanent = True
            session["name"] = nameArr[0]
            session.modified = True

            return {'name' : session["name"]}
    else:    
        return {'name' : "it's not saved to session"}



@app.route("/data", methods=['POST', 'GET'])
def sendData():
    if "name" in session:
        return {'name': session["name"]}
    else 
        return {"name was not in session :("}

通过我的测试,我可以看到它成功登录到所需的 URL 并且可以获取抓取的数据,因此向后端发送数据或使用该数据进行网络抓取没有问题。

据我从 Flask 中的会话文档了解,我的实现应该将数据保存在 session["name"] 中,并将其存储到用户关闭浏览器。但是每当我想使用sendData() 向我的前端发送数据时,它总是打印“name is not in session :(”,这意味着它无法在会话中找到键“name”。

有人猜测为什么会这样:

  • 会话在每次请求后自行重置。
  • 也许它会在我每次发出请求时创建一个新会话。
  • 可能库“请求”和 Flask“请求”相交。

我觉得我不太了解会话的工作原理,而且我在网上找不到足够的信息。

我知道我遗漏了一些东西,有人可以帮忙吗?

另外,我读到会话将数据存储在服务器中,是否有可能将数据存储在客户端浏览器中(如 cookie),如果是这样,你如何实现这样的事情?如果您可以通过在我自己的代码中实现它来解释它,那就太好了!

(如果您需要任何其他信息,请告诉我)

谢谢

【问题讨论】:

  • 我也遇到了同样的问题,但我的前端是 Angular,而不是 React。经过大量搜索,我发现这可能无法实现,所以我放弃了。发生这种情况是因为您的前端和后端托管在不同的端口中,因此烧瓶假定每次请求都是从不同的客户端发出的。因此,您可以首先将数据存储在 cookie 中,然后针对每个请求将存储的 cookie 数据发送到服务器。
  • @ngShravil.py 感谢您的回复,但是如何将 cookie 发送到我的前端端口,我已经尝试过 resp = make_response("setting cookie") resp.set_cookie('name', nameArr[0]) 但同样的情况发生

标签: reactjs session flask python-requests axios


【解决方案1】:

根据我们在 cmets 中的讨论,我们了解到,如果前端和后端都托管在不同的端口中,那么会话不会在 API 调用之间持续存在。

由于同样的原因,现在也无法实现从 Flask 向 React 前端发送 cookie。它仅适用于 Flask 前端。

你可以做一件事,无论你想设置什么作为 cookie,你可以发送它作为 Flask 的响应,然后你可以从 React 设置这些 cookie。对于每个请求,您都必须将此值发送到 Flask。我不熟悉 React,但我在我的 Angular 应用程序中确实喜欢以下内容(这是非常基本的方式):

document.cookie = 'token='+result.token

在 Angular 中,您也可以使用第三方库轻松地做到这一点,以下类似将帮助您:https://itnext.io/angular-8-how-to-use-cookies-14ab3f2e93fc

在 React 中,此链接将对您有所帮助:https://stackoverflow.com/a/43684059/6635464

【讨论】:

  • 谢谢,但是从 react 向我的烧瓶后端发送数据不是问题。问题是:当 Flask 获取该数据时,它会使用它进行网络抓取并获取其他一些数据。在我的前端,当我请求获得的数据时,我什么也得不到,因为它没有保存到某个地方。正如您所说,我尝试了会话,它与 React 不兼容。如果我理解正确,使用 cookie 对我的情况没有帮助,还是我错了?
  • 我希望这会有所帮助。由于 OP 主要是关于会话和 cookie,您能否发布另一个关于网络报废的问题,因为我对此并不熟悉。
【解决方案2】:

您正在发送跨域请求,默认情况下不允许使用 cookie。尝试如下初始化 Flask-CORS:

CORS(app, supports_credentials=True)

更多信息:https://flask-cors.readthedocs.io/en/latest/api.html#using-cors-with-cookies

【讨论】:

    【解决方案3】:

    我也在使用 React,Next.JS 作为前端,Flask 作为后端。

    这个问题很可能是由 CORS 请求引起的,因为您的 React 前端和 Flask 后端不在同一个端口上。

    并且使用Flask-CORS 是要走的路,与@Miguel 确认的相同

    例如CORS(app, supports_credentials=True)

    我正在使用 fetch 在 React 中发送请求,所以包含 credentials: "include" 就可以了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 2015-08-07
      • 1970-01-01
      • 2016-11-12
      • 2020-08-01
      • 2021-02-22
      • 1970-01-01
      相关资源
      最近更新 更多