Flask + React GET请求失败,但POST请求成功

时间:2020-05-12 10:30:28

标签: python reactjs flask fetch

我是React的初学者。我开发了Flask后端,现在我想将其与React搭配使用。

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

这是我的反应代码:

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>)确实被代理到后端服务器,并且我可以在flask中检索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输出。

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"
    },
    "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"
        ]
    }
}

4 个答案:

答案 0 :(得分:1)

最新更新: 抱歉,我对Node.js中的代理人误解了,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 app相同的端口。

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是关于客户端到服务器之间的隧道或其他东西。

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

答案 1 :(得分:0)

我也比较陌生。最近,我写了一个flask API,并使用react前端对其进行测试。为了使工作正常,我做了两件事。

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

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前端和flask api后端之间的连接。希望这对您的问题排查有帮助,并祝您好运。

答案 2 :(得分:-1)

我不确定,但是我认为问题在于您在本地主机上同时使用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"

答案 3 :(得分:-1)

由于您使用的是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"
    ]
}  }