如何在Flask webapp上获取apache来提供静态文件

时间:2015-07-08 16:43:40

标签: python linux apache flask wsgi

我在尝试让Apache提供静态文件时遇到500内部错误。

该应用程序将在本地托管(而不是面向www)。没有DNS可以解析www.domain.com'名称。我想通过在该网络上输入服务器的IP地址来访问应用程序。

这是我的httpd.conf文件(我在RHEL上):

<Directory /var/www/testapp>
  Order allow,deny
  Allow from all
</Directory>

WSGIScriptAlias / /var/www/testapp/service.wsgi

如果我将WSGIScriptAlias更改为WGSIScriptAlias /test /var/www/testapp/service.wsgi,那么当我输入IP时我可以查看我的静态文件,但我仍然无法从[IP] / test访问service.py脚本。 / p>

在任何情况下,我都希望能够使用service.py脚本为所有GET / POST请求提供服务,因此我希望我的别名从/开始,而不是从其他地方开始。

我的所有静态文件都在/ var / www / html中(Apache在我使用httpd.conf之前自动显示这些文件,现在我只是得到了500)。

这是我的service.wsgi:

import sys
sys.path.insert(0, '/var/www/testapp')
from service import app as application

这是我的service.py:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello(environ, start_response):
    status = '200 OK'
    output = "Hello"
    response_headers = [('Content-type', 'text/plain'), ('Content-length', str(len(output)))]
    start_response(status, response_headers)
    return output

if __name__=='__main__'
    app.run()

我是否还需要将我的.wsgi文件保存在/ var / www / html目录中?或者他们可以进入不同的文件夹?我可以看到,我发送到服务器的消息(&#39; Hello&#39;)和已经在/ var / www / html /目录中的静态文件之间可能存在一些冲突。这就是为什么我尝试将别名设置为/test,但这也不起作用。

我只想让我的Flask应用程序为GET / POST请求提供服务,并希望apache能够提供所有静态文件。

1 个答案:

答案 0 :(得分:10)

修复500错误

您目前收到500个错误,因为您的处理程序是一个基本的WSGI处理程序,但Flask处理程序不是WSGI处理程序(Flask / Werkzeug为您提取所有这些内容)。将处理程序更改为:

@app.route("/")
def hello():
    return "Hello"

并且500错误应该消失。

使用Apache

提供静态文件

当您的应用为域的根目录(/)提供服务时,可以使用以下技术,具体取决于您使用的是WSGIScriptAlias还是AddHandler

使用WSGIScriptAlias

使用WSGIScriptAlias/安装WSGI应用程序时,您可以使用Apache Alias指令to ensure that certain sub-routes are not handled by WSGIScriptAlias(这是further documented in mod_wsgi's wiki as well):

Alias "/static/" "/path/to/app/static/"
<Directory "/path/to/app/static/">
  Order allow,deny
  Allow from all
</Directory>

如果您还想支持蓝图静态文件夹,那么 还需要使用AliasMatch指令:

AliasMatch "(?i)^/([^/]+)/static/(.*)$" "/path/to/app/blueprints-root/$1/static/$2"
<Directory ~ "/path/to/app/blueprints-root/[^/]+/static/.*">
  Order allow,deny
  Allow from all
</Directory>

另见:Directory指令。

使用AddHandler

正如Graham Dumpleton在评论中指出的那样,you can use mod_rewrite将请求传递给Python,当且仅当DocumentRoot中不存在文件时。引用链接的文档:

  

当使用AddHandler指令时,由脚本文件扩展名标识的WSGI应用程序,使WSGI应用程序显示为服务器根目录的唯一方法是使用Apache内部的URL执行即时重写mod_rewrite的。 mod_rewrite所需的规则,以确保由脚本文件&#39; site.wsgi&#39;实现的WSGI应用程序。在虚拟主机的根目录中,显示为安装在虚拟主机的根目录上的将是:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L]
     

请注意,当为请求执行WSGI应用程序时,&#39; SCRIPT_NAME&#39;变量指示应用程序的挂载点是&#39; /site.wsgi'。这意味着当WSGI应用程序根据&#39; SCRIPT_NAME&#39;构建绝对URL时,它将包含&#39; site.wsgi&#39;在URL而不是隐藏。由于这可能是不合需要的,许多Web框架提供了一个覆盖挂载点值的选项。如果此类配置选项不可用,则可以轻松调整“SCRIPT_NAME”的价值。在&#39; site.wsgi&#39;脚本文件本身。

from your.app import app  # Your Flask app

import posixpath

def application(environ, start_response):
    # Wrapper to set SCRIPT_NAME to actual mount point.
    environ['SCRIPT_NAME'] = posixpath.dirname(environ['SCRIPT_NAME'])
    if environ['SCRIPT_NAME'] == '/':
        environ['SCRIPT_NAME'] = ''
    return app(environ, start_response)
     

这个包装器将确保&#39; site.wsgi&#39;永远不会出现在网址中,只要它不包含在首位,而且访问始终是通过网站的根目录。