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

pra*_*man 5 python linux apache wsgi flask

我在尝试让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
Run Code Online (Sandbox Code Playgroud)

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

在任何情况下,我希望能够使用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
Run Code Online (Sandbox Code Playgroud)

这是我的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()
Run Code Online (Sandbox Code Playgroud)

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

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

Sea*_*ira 11

修复500错误

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

@app.route("/")
def hello():
    return "Hello"
Run Code Online (Sandbox Code Playgroud)

500错误应该消失.

使用Apache提供静态文件

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

使用时 WSGIScriptAlias

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

Alias "/static/" "/path/to/app/static/"
<Directory "/path/to/app/static/">
  Order allow,deny
  Allow from all
</Directory>
Run Code Online (Sandbox Code Playgroud)

如果您还想支持蓝图静态文件夹,您需要使用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>
Run Code Online (Sandbox Code Playgroud)

另请参见:Directory指令.

使用时 AddHandler

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

使用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]
Run Code Online (Sandbox Code Playgroud)

但请注意,当为请求执行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)
Run Code Online (Sandbox Code Playgroud)

这个包装器将确保"site.wsgi"永远不会出现在URL中,只要它不包含在第一位,并且该访问始终通过网站的根目录而不是.

  • 如果您希望能够将静态文件保存在现有的Apache DocumentRoot目录中而不是将静态文件放在子URL中,那么您需要按照https://code.google.com上的部分说明来调整mod_rewrite./p/modwsgi /维基/ ConfigurationGuidelines#The_Apache_Alias_Directive (2认同)