我是一名网络开发新手,我正在尝试实现一个 Flask + React 应用程序。 在 React 中,我有一个请求 user_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()
将数据发送到前端时,它总是打印“名称不在会话中:(”,这意味着它无法在会话中找到关键的“名称”。
一些猜测为什么会发生这种情况:
我想我不太明白会话是如何工作的,而且我在网上找不到足够的信息。
我知道我错过了一些东西,有人可以帮忙吗?
另外,我读到会话将数据存储在服务器中,是否有可能在客户端浏览器中存储数据(如cookie),如果是的话,你如何实现这样的事情?如果您可以通过将其实现到我自己的代码中来解释它,那就太好了!
(如果您需要任何其他信息,请告诉我)
谢谢
根据我们在评论中的讨论,我们了解到,如果前端和后端托管在不同的端口中,则会话不会在 API 调用之间持续存在。
现在从Flask发送cookie到React前端也无法实现,因为同样的原因。它仅适用于 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
您正在发送跨域请求,默认情况下不允许 cookie。尝试按如下方式初始化 Flask-CORS:
CORS(app, supports_credentials=True)
更多信息:https://flask-cors.readthedocs.io/en/latest/api.html#using-cors-with-cookies。
我还使用 React 和 Next.JS 作为前端,Flask 作为后端。
该问题很可能是由于 CORS 请求造成的,因为您的 React 前端和 Flask 后端不在同一端口上。
使用
Flask-CORS
是正确的方法,与@Miguel相同
例如
CORS(app, supports_credentials=True)
我正在使用
fetch
在 React 中发送请求,因此包含 credentials: "include"
即可完成这项工作
您应该设置一个代理(在react项目的package.json文件中添加“proxy”:“http://127.0.0.1:5000”行)。之后,当您调用 Flask API(使用 axios 或 fetch)时,使用 @app.route 的第一个参数指定的路径(即不带 http://127.0.0.1:5000) 。这样,浏览器就不会将来自 React 前端的请求视为来自不同的来源,因此无需使用 Flask-cors。这对我有用。 更准确地说,在您的 getName 函数中,您将拥有 axios.get('/data')