Python(Flask)服务Angular项目的index.html文件

时间:2018-12-17 23:02:09

标签: javascript python angular flask

有人知道如何使用Flask服务Angular单页应用程序吗?

我在提供默认路由“ /”时遇到了麻烦,该默认路由应加载index.html及其相关组件。这是我的Flask函数:

@app.route('/')
def hello_world():
    return send_file('templates/dist/templates/index.html')

当我访问localhost:5000时,我得到一个空的Chrome浏览器窗口:

Empty Chrome window with Angular / Flask

以及Chrome开发者控制台中的以下错误:

enter image description here

这是在Chrome中显示的内容:

enter image description here

我希望出现错误是因为Flask不知道在哪里可以找到支持文件来渲染Angular组件。按照Angular快速入门教程的指示,我的index.html大部分为空,其中app-root作为HTML主体元素的占位符:

<body>
  <app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>

有人知道如何告诉Flask让Angular渲染页面吗?

3 个答案:

答案 0 :(得分:2)

为简化设置,请考虑在构建过程中使用Angular CLI将所有文件放置在分发目录中,即通过在angular.json中指定outputPath。您可以使用angular.json assets部分在构建过程中移动Python文件。

angular.json

"your-project": {
      "root": "your-project-directory",
      "sourceRoot": "your-project-directory/src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "your-project-directory/src/index.html",
            "main": "your-project-directory/src/main.ts",
            ...

            "assets": [
            {
              "glob": "**/*",
              "input": "your-project-directory/src/assets/",
              "output": "assets"
            },
            {
              "glob": "**/*",
              "input": your-project-directory/src/python/",
              "output": "."
            }

dist目录的顶层,将main.py与基本的Flask设置以及index.html一起放置。请注意 static_proxy 以确保提供支持文件。

main.py

from flask import Flask, send_from_directory

app = Flask(__name__)


@app.route('/<path:path>', methods=['GET'])
def static_proxy(path):
  return send_from_directory('./', path)


@app.route('/')
def root():
  return send_from_directory('./', 'index.html')


if __name__ == '__main__':
  # This is used when running locally only. When deploying use a webserver process 
  # such as Gunicorn to serve the app.
  app.run(host='127.0.0.1', port=8080, debug=True)


@app.errorhandler(500)
def server_error(e):
  return 'An internal error occurred [main.py] %s' % e, 500

答案 1 :(得分:0)

如烧瓶Django Crispy Forms中所述:

  

只需在您的程序包中或模块旁边创建一个名为static的文件夹,即可在应用程序的/ static中找到它。

因此,如果您在以下位置使用模板:

templates/dist/templates/index.html
static/ # set static folder there

或者,取决于您对应用程序进行排序的方式:

templates/dist/static/ # set static folder there

看看他们如何在文档中对应用程序进行排序:

/application.py
/templates
    /hello.html

或者如果您使用模块文件夹:

/application
    /__init__.py
    /templates
        /hello.html

答案 2 :(得分:0)

这是一个古老的问题,但被接受的答案对我不起作用。所以这是我的解决方案,适用于角度路由:


我的文件夹结构:

/angular
    /src
    angular.json
    ... angular project files
/public
    index.html
    ... angular build files
/venv
server.py

在我的 angular.json 中,我将 outputPath 更改为实现上述结构:

"outputPath": "../public"

server.py 中:

import os.path

@app.route("/custom-endpoint")
def custom_endpoint_handler():
    return jsonify(myKey="myValue")


# Serving static files
@app.route('/', defaults={'path': ''})
@app.route('/<string:path>')
@app.route('/<path:path>')
def static_proxy(path):
    if os.path.isfile('public/' + path):
        # If request is made for a file by angular for example main.js
        # condition will be true, file will be served from the public directory
        return send_from_directory('public', path)
    else:
        # Otherwise index.html will be served,
        # angular router will handle the rest
        return app.send_static_file("index.html")

脚注:我是烧瓶的新手。因此,欢迎对存在任何错误的任何改进或修复。