【问题标题】:Unable to render create-react-app boilerplate views from Flask backend无法从 Flask 后端呈现 create-react-app 样板视图
【发布时间】:2017-11-14 14:27:21
【问题描述】:

我很难将 create-react-app 单页应用程序集成到我的烧瓶后端。我希望能够像这样从前端进行 fetch/axios 调用:axios.get('/getResults') 和 fetch('/getResults')。我尝试过但不限于将 Flask 端口指定为 3000,这与 create-react-app 使用的相同。此外,在 create-react-app 的“package.json”文件中使用了代理配置功能,但无济于事。我怀疑我的文件夹结构和 Flask 代码实现可能会导致这种情况。下面是我的文件夹结构和“app.py”代码。我能得到的任何帮助将不胜感激。如有必要,我可以提供更多信息。谢谢

项目
-build(包含静态文件夹,index.html...其他元文件)
-node_modules
-public
-src
app.py
包。 json
requirements.txt

app.py:

from flask import Flask, Response, request, jsonify, make_response, send_from_directory,render_template

app = Flask(__name__, static_path='/build/static/')
app.debug=True

@app.route('/')
def root():
    print('Inside root function')
    return app.send_static_file('index.html')

@app.route('/getResults', methods=["GET"])
def results():
    print('Inside getResults path')
    return app.send_static_file('index.html')

@app.route('/postData', methods=["POST"])
def data_results():
    print('Inside postData path')
    data = request.get_json
    return jsonify(data)

@app.route('/<path:path>')
def send_js(path):
    print("inside send_js fxn")
    return send_from_directory('./build/static',path)


if __name__ == "__main__":
    print("inside main host call")
    app.run(host='0.0.0.0', port=3000)

我在运行“python app.py”时遇到的错误是:

在终端上:根函数内部 127.0.0.1 - - [12/Jun/2017 09:42:24] “GET / HTTP/1.1”404 -

在浏览器上:未找到 - 在服务器上未找到请求的 URL。如果您手动输入了 URL,请检查您的拼写并重试。

【问题讨论】:

  • 你是如何使用 npm start 运行 create-react-app 的?
  • 我使用 yarn start 和 yarn build 运行它,这样我就可以将静态文件用于烧瓶后端
  • @dlvr 你看我的回答了吗stackoverflow.com/a/45245402/140837

标签: python reactjs flask create-react-app


【解决方案1】:

我认为你有很多误解。

create-react-app 在其自己的服务器上的 3000 端口上运行,如果您尝试在同一台机器上的同一端口上运行您的烧瓶应用程序,它会抱怨端口 3000 已在使用中。所以从这里我们转移到另一个问题 - 你的应用程序的结构。

它会是一个单独的基于 reactjs 的前端客户端和基于 api 的后端烧瓶,这将是 2 个通过 HTTP 相互通信的独立应用程序?在这种情况下,前端和后端通常会在不同的服务器上运行。

或者它将是一个在其模板页面中使用 reactjs 的烧瓶应用程序?

您可以通过在代码中更改此来解决当前找不到 URL 的问题:

@app.route('/')
def root():
    print('Inside root function')
    return render_template('index.html')

还有这个:

template_dir = os.path.abspath('build/templates')
app = Flask(__name__, static_path='/build/static/',
            template_folder=template_dir)

因为您的模板文件夹位于build 目录中。

【讨论】:

  • 感谢@Nurzhan 的回复。即使我将端口更改为5000并使用您上面推荐的sn-p,它仍然不成功。此外,我将一些元文件和 index.html 移动到构建文件夹中的模板文件夹中。现在我的构建文件夹是这样的: -build --static(contains: js,css and media) --templates(contains: index.html, asset-manifest.json,manifest.json, service-worker.js, favicon. ico)
  • @dlvr 有什么反应?还是没有找到吗?这个对我有用。可能你没有完全按照我写的那样做。已决定您将为您的应用使用什么架构?
  • 这些是来自终端的响应: 根函数内部 127.0.0.1 - - [12/Jun/2017 23:11:50] "GET / HTTP/1.1" 200 - 在 send_js fxn 127.0.0.1 - - [12/Jun/2017 23:11:50] “GET /static/css/main.9a0fe4f1.css HTTP/1.1” 404 - 在 send_js fxn 127.0.0.1 - - [12 /Jun/2017 23:11:50]“GET /static/js/main.50dca1bb.js HTTP/1.1”404 -
  • @dlvr 您要访问什么 URL?它抱怨找不到他的css和js文件。他们出现在这些地方吗?
  • 我按照你的建议做了: template_dir = os.path.abspath('build/templates') app = Flask(name, static_path= '/build/static/', template_folder=template_dir) app.debug=True if name == "main": print("inside main host call") app.运行(主机='0.0.0.0',端口=5000)
【解决方案2】:

我遇到了完全相同的问题,我可以通过使用符号链接安抚 Flask 来解决它。

将模板和静态目录路径保留为默认值,并在包含 Flask 主文件的目录中,添加这些符号链接

ln -s build/ templates
ln -s build/static static

如果您好奇,这是我的具体问题,它只是涉及更多嵌套目录,但本质上是相同的:

Running NPM Build from Flask

然后你就可以使用Nurzhan的root配置了:

@app.route('/')
def root():
    print('Inside root function')
    return render_template('index.html')

但您只需要将您的应用声明为:app = Flask(__name__)

唯一对我不起作用的是图标,一旦我弄清楚了,我会更新这个答案。

【讨论】:

  • 如何在该配置下使用热重载?
  • @amirouche 我实际上不确定是否很诚实。如果您有使用单一来源的热重载和 API 的解决方案,那么我很乐意听到它,因为我的应用程序也需要它。但是,我没有使用 Ajax,仅使用 axios 进行反应。
  • 你看了我的回答stackoverflow.com/a/45245402/140837还有我在github.com/amirouche/socialite有一个项目使用它
  • @amirouche 您的网站是生产版本吗?根据这篇文章,proxy 字段只会在开发模式下解析为npm start。生产版本将引发 CORS 错误。 github.com/facebookincubator/create-react-app/blob/master/…
  • 不,这不是生产版本。
【解决方案3】:

在开发模式下,您需要配置您的 create-react-app package.json 以将“ajax”请求转发到烧瓶服务器。

这是我的package.json 的样子:

{
  "name": "socialite",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:8080",
  "devDependencies": {
    "react-scripts": "1.0.10"
  },
  "dependencies": {
    "react": "^15.6.1",
    "react-dom": "^15.6.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

看到proxy 字段了吗?这就是魔法发生的地方,用烧瓶服务器地址替换它的值。这样,您就可以利用 CRA 热重载功能。这记录在create-react-app as "Proxying API Requests in Development"

然后运行您的应用程序,您可以访问localhost:3000 或任何为您打开的端口 yarn。当你在 javascript 中通过 Rainbow 对服务器进行 API 调用时,例如:fetch('/api/model/') 或 nodejs 的服务器将转发到烧瓶应用程序。我认为 nodejs 服务器确实会查看 ajax 请求的 content-type 字段,以了解它是否应该将请求转发到后端服务器。

我建议您在所有后端路由前加上 /api/v1/ 之类的前缀,以便 nginx 配置简洁且易于编写。

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2016-10-05
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多