【问题标题】:Flask + React GET Request is failing but POST Request is successfulFlask + React GET 请求失败但 POST 请求成功
【发布时间】:2020-08-28 03:46:24
【问题描述】:

我是 React 的初学者。我开发了一个 Flask 后端,现在我想将它与 React 配对作为前端。

我在 React 中使用 fetch 来发出 GET 请求。当我读取数据时,调用response.text() 时的文本或响应是我的应用程序public 目录中的index.html 文件

这是我的反应代码:

componentDidMount() {
    fetch('/')
      .then(response => {
        console.log(response.text()) //Here is the text() i said before
        this.setState({ snippets: response.data })
      })
      .catch(error=>{
        console.log(error)
      })
  }

这是我的烧瓶应用程序的 MRE:

@app.route('/')
def index():
    return {'snippets':['blah','blaha']

我在package.json中的代理

    "proxy": "http://127.0.0.1:5000/"

我的烧瓶后端在 5000 端口运行,并在 3000 端口做出反应

需要注意的一点是 POST 请求(来自<form>)确实被代理到后端服务器,我可以在烧瓶中检索 POST 请求的内容。使用 fetch 的 GET 请求不起作用。

目录结构:

-env
-getcode
  -templates
  -static
  -__init__.py
  -routes.py
-getcode-client
  -src
  -public
run.py

这里getcode是flask应用的目录,getcode-client包含使用create-react-app创建的React应用

注意: 我也尝试像这样设置手动代理:https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually

但现在没有显示 react 应用程序。它完全显示了我的烧瓶后端的 json 输出。

包.json:

{
    "name": "getcode-client",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@testing-library/jest-dom": "^4.2.4",
        "@testing-library/react": "^9.3.2",
        "@testing-library/user-event": "^7.1.2",
        "axios": "^0.19.2",
        "http-proxy-middleware": "^1.0.3",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "react-router-dom": "^5.1.2",
        "react-scripts": "3.4.1"
    },
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": {
        "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
        ],
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
        ]
    }
}

【问题讨论】:

  • 也许flask在/路由上提供了一些index.html文件,你能用/api替换/然后再试一次。
  • 没有提供模板

标签: python reactjs flask fetch


【解决方案1】:

最新更新: 对不起,我误解了nodejs中的代理,fetch()可以支持这种代理。

在我做了一些试验和错误之后,您只需将路径“/”更改为“/something_else”,代理就可以正常工作了。

@app.route('/test', methods=['GET', 'POST'])
def index():
    return {'snippets':['blah','blaha']}
componentDidMount() {
    fetch('/test')
      .then(response => {
        console.log(response.text()) //Here is the text() i said before
        this.setState({ snippets: response.data })
      })
      .catch(error=>{
        console.log(error)
      })
  }

错误信息:

这不是python和flask的问题。

你在javascript中使用fetch(),这是原生js函数,所以和你在package.json中设置的代理无关。

如果你想使用fetch() 来获取其他端口,你必须给它整个 url http://localhost:5000/ 否则你会得到你的 react 应用程序的相同端口。

fetch('http://localhost:5000/')
      .then(response => {
        console.log(response.text()) //Here is the text() i said before
        this.setState({ snippets: response.data })
      })
      .catch(error => {
        console.log(error)
      });

您可以使用一些包,例如fetch-with-proxynode-https-proxy-agent,fetch-with-proxy 可以获取HTTP_PROXY env var 来设置代理,您可以使用其他创建代理。

但我建议使用其他包发送请求,如axios

import axios from 'axios';
const axios_ = axios.create({
  baseURL: 'http://localhost:5000',
  headers: { 'Content-Type': 'application/json' },
})

class App extends React.Component  {
  componentDidMount() {
    axios_.get('/')
      .then(response => {
        console.log(response.text()) //Here is the text() i said before
        this.setState({ snippets: response.data })
      })
      .catch(error => {
        console.log(error)
      });
  }
...}

其实你说的proxy并不是我们平时说的proxy,你要做的只是指向另一个端口来获取响应。

Proxy 是关于客户端到服务器之间的隧道或其他东西。

此外,您还可以搜索反向代理,这也是您想知道的问题。

【讨论】:

  • 所以我知道你必须在生产中使用 nginx。有没有办法在开发中使用 nginx 反向代理。在我的本地机器上??
  • 在我搜索更多信息后,我误解了 package.json 中的代理。我认为是nodejs代理问题,它不支持根路径'/'。如果在 fetch 和 flask 路由中将 '/' 更改为 '/test' 或其他,它可以工作。
  • 我曾尝试在 package.json 中使用 /api 但这也不起作用
  • 所以在 package.josn 中的代理是 http;//localhost:5000/test
  • 是的,现在可以了。是的,两台服务器都处于调试模式,自动重新加载工作
【解决方案2】:

我不确定,但我认为问题在于您在 localhost 上同时使用 React 和 Flask,并且没有在 fetch 请求中指定端口,试试这个:

componentDidMount() {
    fetch('/:5000')
      .then(response => {
        console.log(response.text()) //Here is the text() i said before
        this.setState({ snippets: response.data })
      })
      .catch(error=>{
        console.log(error)
      })
  }

或者如果这没有帮助,可以将代理设置更改为:

"proxy": "127.0.0.1:5000"

【讨论】:

  • 问题是我不想输入 localhost。我想 fetch 将所有请求代理到我的烧瓶后端。
  • 试试/:5000 怎么样,它应该通过flask 代理所有请求。我会编辑我的答案。
【解决方案3】:

我对反应也比较陌生。最近我写了一个烧瓶 API 并用一个反应前端来测试它。为了让事情顺利进行,我做了两件事。

  1. 我的componentDidMount 使用docs 看起来像这样

componentDidMount() {
  fetch('/').then(response => {
    return response.text();
  }).then(response => {
    this.setState({ snippets: response.data })
  }).catch(error=>{
    console.log(error)
  });
}
  1. 我使用flask_cors 包来防止CORS 相关问题。实现将是这样的
from flask_cors import cross_origin


@cross_origin(origin="*")
@app.route('/')
def index():
   return {'snippets':['blah','blaha']

我没有对我的package.json 进行任何更改以获取 React 前端和烧瓶 api 后端之间的连接。希望这对您的故障排除有所帮助并祝您好运。

【讨论】:

    【解决方案4】:

    由于您使用的是 CRA,我建议您使用他们的代理设置。

    要告诉开发服务器将任何未知请求代理到开发中的 API 服务器,请在您的 package.json 中添加一个代理字段,例如:

    "proxy": "http://localhost:4000",
    

    在您的情况下,这将在端口 5000 上。

    Here 的主题更多。

    但是,在生产中,我建议使用 nginx 或 apache 以避免将来出现问题。

    @编辑 这就是 package.json 在您的情况下的外观

    {
    "name": "getcode-client",
    "version": "0.1.0",
    "private": true,
    "dependencies": {
        "@testing-library/jest-dom": "^4.2.4",
        "@testing-library/react": "^9.3.2",
        "@testing-library/user-event": "^7.1.2",
        "axios": "^0.19.2",
        "http-proxy-middleware": "^1.0.3",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "react-router-dom": "^5.1.2",
        "react-scripts": "3.4.1"
    },
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
    },
    "proxy": "http://localhost:5000",
    "eslintConfig": {
        "extends": "react-app"
    },
    "browserslist": {
        "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
        ],
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
        ]
    }  }
    

    【讨论】:

    • 应该有,您是否尝试过重新启动应用程序&您是否将它放在 package.json 中的正确位置?你能不能把它放到你的主要职位上?整个 package.json
    • package.json 是正常的,由 create 创建并添加了代理。是的,我已经重新启动了服务器,甚至重新启动了计算机
    • 对,我只是想确保您将代理 sn-p 放置在正确的位置。此外,如果能从您的开发者控制台中看到一张关于它如何处理请求的图片,那就太好了。
    • 我已经添加了 package.json
    • 是的,但我在这里没有看到代理 sn-p?我已经编辑了我的帖子,将其复制为您的新 package.json 并重新启动您的 react 应用程序,让我知道它是如何进行的。
    猜你喜欢
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 2017-05-22
    • 2014-07-24
    • 2023-03-14
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多