如何让Apache在Flask webapp上提供静态文件

我在尝试让Apache服务我的静态文件时遇到500内部错误。

该应用程序将在本地托pipe(而不是www面临)。 将不会有DNS解决“www.domain.com”的名称。 我希望能够通过input服务器的IP地址访问应用程序,当我在networking上。

这是我的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则可以在inputIP时查看我的静态文件,但仍然无法从[IP] /testing。

无论如何,我希望能够使用service.py脚本来处理所有GET / POST请求,所以我希望我的别名从/开始,而不是其他地方。

我所有的静态文件都在/ var / www / html中(在我弄乱了httpd.conf之前,Apache会自动显示这些文件,现在我只得到一个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目录中? 或者他们可以在不同的文件夹中? 我可以看到,我发送给服务器的消息('Hello')和已经在/ var / www / html /目录下的静态文件之间可能存在一些冲突。 这就是为什么我试图设置别名/test但也没有工作。

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

解决500个错误

你目前得到500错误,因为你的处理程序是一个基本的WSGI处理程序,但Flask处理程序不是WSGI处理程序(Flask / Werkzeug为你抽象)。 改变你的处理程序:

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

500个错误应该消失。

使用Apache提供静态文件

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

使用WSGIScriptAlias

当使用WSGIScriptAlias/安装WSGI应用程序时,您可以使用Apache Alias指令来确保某些子路由WSGIScriptAlias处理 (这在mod_wsgi的wiki中也有记录 ):

 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在注释中指出的,当且仅当DocumentRoot中不存在文件时,才可以使用mod_rewrite将请求传递给Python。 引用链接的文档:

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

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

但请注意,当为请求执行WSGI应用程序时,指示应用程序的挂载点的“SCRIPT_NAME”变量将是“/site.wsgi”。 这意味着当一个WSGI应用程序构造一个基于“SCRIPT_NAME”的绝对URL时,它将在URL中包含“site.wsgi”,而不是被隐藏。 由于这可能是不可取的,许多Web框架提供了一个选项来覆盖挂载点的值。 如果这样的配置选项不可用,则在“site.wsgi”脚本文件本身中调整“SCRIPT_NAME”的值同样简单。

 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) 

这个包装器将确保“site.wsgi”永远不会出现在URL中,只要它不在第一个地方,并且访问总是通过网站的根目录。