Flask w/ Apache & FCGI 路由问题
Flask w/ Apache & FCGI routing problems
所以我一直在使用 Flask 和 Bootstrap 在 Apache 服务器上工作。我已经到了可以访问应用程序并使用以下路线呈现 "first" 或 "main" 模板的地步:
来自 view.py:
@app.route('/')
def fn_home():
return render_template("main.html")
不幸的是,每次尝试从 main.html 路由到另一个 webpage/function 都会失败。我在导航栏列表 href 中使用 "url_for" 函数,试图让 Flask 向 Apache 提供 xls-upload.html 网页。
来自 main.html:
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('upload') }}">Upload Spreadsheets </a></li>
来自 view.py:
@app.route('/upload')
def upload():
return render_template("xls-upload.html")
看起来函数正在使用,因为 URL 更改为 http://myapp/upload,但是 html 页面不是函数 rendered/returned - 相反我收到 404 "Not Found"。我似乎无法 return 函数中的任何内容,甚至 return "Hello World"
.
它 "seems" 就像 Apache 一样,实际上是在尝试解析 http://myapp/upload 路径,而不是向 Flask 应用程序打开一个套接字,然后通过该套接字发送 html。我不确定这是否是一个 FCGI 问题,如果我遗漏了一个 relative/absolute 路径问题,误解了 Flask 的一般工作方式,或者所有问题的某种组合,等等
我是 Flask 的新手,所以我希望有人能一路帮助我,因为我真的觉得我已经走到了死胡同。
提前致谢!
我的 flask 应用程序结构如下:
- var/www/cgi-bin/myapp/(根目录)
- start.fcgi
- view.py(烧瓶routing/app文件)
- 静态(目录)
- bootstrap 个文件
- 模板(目录)
- main.html
- xls-upload.html
以下是我的适用文件:
1) /etc/httpd/conf.d/myapp:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/cgi-bin/myapp/static/
ServerName myapp
Alias /static/ /var/www/cgi-bin/myapp/static/
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi
<Directory "var/www/cgi-bin/myapp">
AllowOverride None
Order allow,deny
Allow from all
AuthType Basic
AuthUserFile /etc/httpd/.htpasswd
AuthName 'Enter Password'
Require valid-user
</Directory>
</VirtualHost>
2) /var/www/cgi-bin/myapp/start.fcgi:
#!/usr/bin/python
# IMPORTS:
from flup.server.fcgi import WSGIServer
from view import app
if __name__ == '__main__':
WSGIServer(app).run()
3) /var/www/cgi-bin/myapp/view.py:
#!/usr/bin/python
# IMPORTS:
import os
from flask import Flask, render_template, url_for, request, session, redirect
from werkzeug import secure_filename
# STATIC VARIABLES
UPLOAD_FOLDER = 'var/www/cgi-bin/myapp/xls-dir'
ALLOWED_EXTENSIONS = set(['xls'])
## flask:
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# FUNCTIONS
def fn_allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@app.route('/')
def fn_home():
return render_template("main.html")
@app.route('/upload')
def upload():
return render_template("xls-upload.html")
#return "HI there"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
4) /var/www/cgi-bin/myapp/templates/main.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG Tools HOME</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('upload') }}">Upload Spreadsheets </a></li>
<li><a href="/xls-download.html">Download Spreadsheets</a></li>
<li><a href="/cfg-generate.html">Generate Configs</a></li>
</ul>
</div>
</div>
</nav>
<body>
<h2>ALG stuff</h2>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
5) /var/www/cgi-bin/myapp/templates/xls-upload.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG XLS Upload</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/xls-upload.html">Upload Spreadsheets </a></li>
<li><a href="/xls-download.html">Download Spreadsheets</a></li>
<li><a href="/cfg-generate.html">Generate Configs</a></li>
</ul>
</div>
</div>
</nav>
<body>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
FCGI 并不是真正推荐的 Python 网络应用服务方式。您应该研究 运行ning WSGI 的多种方法之一。
但是,假设您出于某种原因需要执行此操作,则您遇到了一个小配置问题,这就是问题的原因;您需要在 ScriptAlias 路径上添加尾部斜杠。
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi/
有了这个,Apache 将把完整路径传递给 start.fcgi 脚本,而不是替换它。
请注意,即使使用 FCGI,您也不应将您的应用程序代码放在 cgi-bin 中。它不需要存在,因为它不像 CGI 应用程序那样由 Web 服务器 运行。事实上,您的代码根本不应该在 /var/www 之下。
所以我一直在使用 Flask 和 Bootstrap 在 Apache 服务器上工作。我已经到了可以访问应用程序并使用以下路线呈现 "first" 或 "main" 模板的地步:
来自 view.py:
@app.route('/')
def fn_home():
return render_template("main.html")
不幸的是,每次尝试从 main.html 路由到另一个 webpage/function 都会失败。我在导航栏列表 href 中使用 "url_for" 函数,试图让 Flask 向 Apache 提供 xls-upload.html 网页。
来自 main.html:
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('upload') }}">Upload Spreadsheets </a></li>
来自 view.py:
@app.route('/upload')
def upload():
return render_template("xls-upload.html")
看起来函数正在使用,因为 URL 更改为 http://myapp/upload,但是 html 页面不是函数 rendered/returned - 相反我收到 404 "Not Found"。我似乎无法 return 函数中的任何内容,甚至 return "Hello World"
.
它 "seems" 就像 Apache 一样,实际上是在尝试解析 http://myapp/upload 路径,而不是向 Flask 应用程序打开一个套接字,然后通过该套接字发送 html。我不确定这是否是一个 FCGI 问题,如果我遗漏了一个 relative/absolute 路径问题,误解了 Flask 的一般工作方式,或者所有问题的某种组合,等等
我是 Flask 的新手,所以我希望有人能一路帮助我,因为我真的觉得我已经走到了死胡同。
提前致谢!
我的 flask 应用程序结构如下:
- var/www/cgi-bin/myapp/(根目录)
- start.fcgi
- view.py(烧瓶routing/app文件)
- 静态(目录)
- bootstrap 个文件
- 模板(目录)
- main.html
- xls-upload.html
以下是我的适用文件:
1) /etc/httpd/conf.d/myapp:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/cgi-bin/myapp/static/
ServerName myapp
Alias /static/ /var/www/cgi-bin/myapp/static/
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi
<Directory "var/www/cgi-bin/myapp">
AllowOverride None
Order allow,deny
Allow from all
AuthType Basic
AuthUserFile /etc/httpd/.htpasswd
AuthName 'Enter Password'
Require valid-user
</Directory>
</VirtualHost>
2) /var/www/cgi-bin/myapp/start.fcgi:
#!/usr/bin/python
# IMPORTS:
from flup.server.fcgi import WSGIServer
from view import app
if __name__ == '__main__':
WSGIServer(app).run()
3) /var/www/cgi-bin/myapp/view.py:
#!/usr/bin/python
# IMPORTS:
import os
from flask import Flask, render_template, url_for, request, session, redirect
from werkzeug import secure_filename
# STATIC VARIABLES
UPLOAD_FOLDER = 'var/www/cgi-bin/myapp/xls-dir'
ALLOWED_EXTENSIONS = set(['xls'])
## flask:
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# FUNCTIONS
def fn_allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
@app.route('/')
def fn_home():
return render_template("main.html")
@app.route('/upload')
def upload():
return render_template("xls-upload.html")
#return "HI there"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
4) /var/www/cgi-bin/myapp/templates/main.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG Tools HOME</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="{{ url_for('upload') }}">Upload Spreadsheets </a></li>
<li><a href="/xls-download.html">Download Spreadsheets</a></li>
<li><a href="/cfg-generate.html">Generate Configs</a></li>
</ul>
</div>
</div>
</nav>
<body>
<h2>ALG stuff</h2>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
5) /var/www/cgi-bin/myapp/templates/xls-upload.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG XLS Upload</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/xls-upload.html">Upload Spreadsheets </a></li>
<li><a href="/xls-download.html">Download Spreadsheets</a></li>
<li><a href="/cfg-generate.html">Generate Configs</a></li>
</ul>
</div>
</div>
</nav>
<body>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
FCGI 并不是真正推荐的 Python 网络应用服务方式。您应该研究 运行ning WSGI 的多种方法之一。
但是,假设您出于某种原因需要执行此操作,则您遇到了一个小配置问题,这就是问题的原因;您需要在 ScriptAlias 路径上添加尾部斜杠。
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi/
有了这个,Apache 将把完整路径传递给 start.fcgi 脚本,而不是替换它。
请注意,即使使用 FCGI,您也不应将您的应用程序代码放在 cgi-bin 中。它不需要存在,因为它不像 CGI 应用程序那样由 Web 服务器 运行。事实上,您的代码根本不应该在 /var/www 之下。