【问题标题】:Flask w/ Apache & FCGI routing problems带有 Apache 和 FCGI 路由问题的 Flask
【发布时间】:2015-12-15 12:16:36
【问题描述】:

所以我一直在使用 Flask 和 Bootstrap 在 Apache 服务器上工作。我已经达到了可以访问应用程序并使用以下路线呈现“第一个”或“主”模板的地步:

来自 view.py:

@app.route('/')
def fn_home():
    return render_template("main.html")

不幸的是,每次从 main.html 路由到另一个网页/功能的尝试都失败了。我在导航栏列表href中使用“url_for”函数,试图让flask将xls-upload.html网页提供给Apache。

来自 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 页面 - 而是收到 404“未找到”。我似乎无法从函数中返回任何内容,即使是 return "Hello World"

“似乎”Apache 真的在尝试解析http://myapp/upload 路径,而不是向Flask 应用程序打开一个套接字,然后通过该套接字发送html。我不确定这是否是 FCGI 问题,是否缺少相对/绝对路径问题,是否误解了 Flask 的一般工作原理,或者所有这些问题的某种组合等等。

我是 Flask 的新手,所以我希望有人能一路帮助我,因为我真的觉得自己走到了死胡同。

提前致谢!

我的烧瓶应用结构如下:

  • var/www/cgi-bin/myapp/(根目录)
    • start.fcgi
    • view.py(flask 路由/应用文件)
    • 静态(目录)
      • 引导文件
    • 模板(目录)
      • 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>

【问题讨论】:

    标签: python apache twitter-bootstrap-3 flask fastcgi


    【解决方案1】:

    FCGI 并不是提供 Python Web 应用程序的真正推荐方式。您应该研究运行 WSGI 的多种方式之一。

    但是,假设您出于某种原因需要执行此操作,那么您有一个较小的配置问题,这就是您的问题的原因;您需要在 ScriptAlias 路径上添加一个斜杠。

    ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi/
    

    这样,Apache 会将完整路径传递给 start.fcgi 脚本,而不是替换它。

    请注意,即使使用 FCGI,您也不应该将您的应用代码放在 cgi-bin 中。它不需要在那里,因为它不像 CGI 应用程序那样由 Web 服务器运行。事实上,您的代码甚至根本不应该在 /var/www 下。

    【讨论】:

    • 您好丹尼尔,非常感谢您的回答,它立即允许路由工作!埃文虽然这有效,但我仍然不明白为什么......我希望你可以扩展斜杠,apache,flask交互?当您点击 url_for 链接时,main.html、flask 和 apache 之间究竟发生了什么?
    • main.html 与任何东西无关。区别仅在于路径的处理方式;使用尾部斜杠,任何后续路径都将添加到 scriptalias 路径,因此它通过 start.fcgi 文件并传递给flup。没有它,路径 replaces start.fcgi;这与您在浏览器中的路径 /foo/bar.html 上并导航到 baz.html 完全相同,您最终会到达 /foo/baz.html 而不是 /foo/bar.html/baz.html。
    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 2021-02-11
    • 2017-10-25
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多