部署Angular+Flask+Apache时页面刷新显示后端JSON问题排查
我正尝试部署一个Angular+Flask演示应用到Apache服务器,项目目录为/var/www/backend/basicapp/,包含app.py、app.wsgi及存放Angular构建文件的static文件夹(含index.html)。
相关代码
app.py
from flask import Flask, jsonify, render_template from flask_cors import CORS, cross_origin app = Flask(__name__) CORS(app) @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def catch_all(path): return app.send_static_file('index.html') @app.route('/facts') def facts(): return jsonify("Honey never spoils. Archaeologists have found pots of honey in ancient Egyptian tombs that are over 3,000 years old!") @app.route('/jokes') def jokes(): return jsonify("Why don't scientists trust atoms? Because they make up everything!") if __name__=='__main__': app.run()
app.wsgi
import sys import logging sys.path.insert(0, '/var/www/basicapp/backend') from app import app as application
Apache虚拟主机配置(httpd.conf)
<VirtualHost *:80> ServerName 192.170.160.71 WSGIDaemonProcess basicapp user=apache group=apache threads=5 WSGIScriptAlias /basicapp /var/www/basicapp/backend/app.wsgi <Directory /var/www/basicapp/backend> WSGIProcessGroup basicapp WSGIApplicationGroup %{GLOBAL} Require all granted </Directory> ErrorLog /var/www/basicapp/backend/logs/error.log CustomLog /var/www/basicapp/backend/logs/access.log combined </VirtualHost>
问题现象
启动Apache后,访问192.170.160.71/basicapp/可正常显示首页,通过首页按钮进入/facts和/jokes路由也能正常渲染前端UI;但直接访问或刷新这两个路由时,页面会显示后端返回的JSON数据而非前端UI。曾尝试使用render_template(index.html),后参考Flask的SPA文档添加catch_all路由,但问题仍未解决。
问题核心是Flask的API路由与Angular前端路由路径冲突,直接访问时请求会优先匹配后端API路由,而非SPA的catch_all路由。具体解决步骤如下:
1. 给API路由添加统一前缀
修改app.py,为所有后端API路由加上/api前缀,避免和前端路由重名:
# 替换原有/facts和/jokes路由 @app.route('/api/facts') def facts(): return jsonify("Honey never spoils. Archaeologists have found pots of honey in ancient Egyptian tombs that are over 3,000 years old!") @app.route('/api/jokes') def jokes(): return jsonify("Why don't scientists trust atoms? Because they make up everything!")
同时调整Angular代码中调用API的路径,将原来的/facts、/jokes改为/basicapp/api/facts、/basicapp/api/jokes(可根据项目环境配置动态调整)。
2. 确保catch_all路由正确捕获前端路由请求
保留原有的catch_all路由,由于API路由已带前缀,Flask会优先匹配精确的API路由,其余前端路由请求会被catch_all捕获并返回index.html,交由Angular处理前端路由。
另外,可显式指定Flask的静态文件目录,确保能正确读取Angular构建文件:
# 初始化Flask时指定static目录和URL路径 app = Flask(__name__, static_folder='static', static_url_path='')
3. 验证Apache配置与权限
- 确认
WSGIScriptAlias路径正确指向app.wsgi文件; - 确保Apache用户(apache)对
/var/www/basicapp/backend目录及子文件有读写权限,尤其是logs文件夹。
内容的提问来源于stack exchange,提问作者AbhirChavan

