首页 > 解决方案 > 如何从 React Form -> Flask Backend -> React Component 传递数据(它是否与 CORS 有关)?

问题描述

嗨,我是一个完整的 React 初学者,并且有一个相当基本的问题。我希望执行以下步骤:

(1) 为用户提供一个表单来输入一些文本 (2) 将输入提取到 Flask 后端并在执行一些操作后返回一个新值 (3) 在前端视图中将 (2) 的结果提供给用户

我希望这个过程是一个单页应用程序,用户不会在步骤 (3) 中被重定向到另一个页面。

这是我的 App.js 代码:

import React from 'react';
import './App.css';

class App extends React.Component {

 constructor(props) {
    super(props);
    this.state = {value: '',
                  playerName: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    console.log("making request")
    fetch('/result')
      .then(response => {
        console.log(response)
        return response.json()
      })
      .then(json => {
      console.log=(json)
      this.setState({playerName: json[0]})
      })
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit} action="http://localhost:5000/result" method="get">
        <label>
          Player ID:
          <input type="text" name="player_id"/>
          <input type="submit" onChange={this.handleChange} value={this.state.value} />
        </label>
      </form>
        <h1> Player Name: {this.state.playerName} </h1>
      </div>
    );
  }
}


export default App

这是我的 main.py 代码:

from flask import Flask, request, jsonify, send_from_directory
from sqlalchemy import create_engine
import pandas as pd

app = Flask(__name__, static_folder='../frontend/build')

@app.route('/result', methods = ['GET'])
def result():
    if request.method == 'GET':
        player_id = request.args.get('player_id', None)
        if player_id:
            data = get_player(player_id)
            name = str(data['name'][0])
            return jsonify(name)
        return "No player information is given"


def get_player(player_id):
    engine = create_engine(
        'postgres://fzmokkqt:********************-***-******-@********.com:*****/******')
    sql = """SELECT * from players WHERE id={player_id}"""
    data = pd.read_sql_query(sql.format(player_id=player_id), con=engine)
    return data

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def serve(path):
    if path != "" and os.path.exists("frontend/build/" + path):
        return send_from_directory('../frontend/build', path)
    else:
        return send_from_directory('../frontend/build', 'index.html')

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

当我运行此代码时,我收到了预期的结果,但是它没有按照 App.js 代码中的描述放置在 HTML 中。相反,结果被渲染到一个新页面(在 localhost:5000 而不是 localhost:3000 上,这是渲染 React 代码的地方)。

标签: javascriptpythonreactjsflask

解决方案


将数据发送到烧瓶后端是 POST 请求,但您使用的是 GET 请求。所以你在 React js 中的 fetch 应该是

   fetch("/result", {
        method:"POST",
        cache: "no-cache",
        headers:{
            "content_type":"application/json",
        },
        body:JSON.stringify(this.state.value)
        }
    ).then(response => {

    return response.json()
  })
  .then(json => {

  this.setState({playerName: json[0]})
  })

您的烧瓶方法也应该是 POST 方法

@app.route('/result', methods = ['POST'])
def result():
    player_id = request.json
    if player_id:
       data = get_player(player_id)
       name = str(data['name'][0])
       return jsonify(name)
   return "No player information is given"

你的烧瓶中需要 CORS,所以

pip install flask-cors 然后在你的代码中

from flask_cors import CORS

app = Flask(__name__, static_folder='../frontend/build')

CORS(app)

此外,您还可以发布您的 react js 包,因此请确保您在 package.json 中添加了代理,如下所示

  "name": "client",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://0.0.0.0:5000",

我假设您的其余代码有效,所以这只是为了回答您关于在 Flask 和 React JS 之间建立连接的问题。

您将能够从 React 接收烧瓶中的数据,但是将 json 数据从烧瓶中的数据库发送到 reactjs 时会遇到问题。对于数据库处理,我通常使用 Flask-SQLAlchemy,我从数据库中获取的数据不是 json 对象,所以我必须将模型序列化为 JSON,这通过一个名为 flask-marshmellow 的包来实现。所以看看使用这两个包


推荐阅读