草庐IT

python - 如何让apache在Flask webapp上提供静态文件

coder 2023-06-20 原文

我在尝试让 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 脚本。

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

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

这是我的服务.wsgi:

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

这是我的服务.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指令 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当且仅当 DocumentRoot 中不存在文件时,才将请求传递给 Python。引用链接文档:

When using the AddHandler directive, with WSGI applications identified by the extension of the script file, the only way to make the WSGI application appear as the root of the server is to perform on the fly rewriting of the URL internal to Apache using mod_rewrite. The required rules for mod_rewrite to ensure that a WSGI application, implemented by the script file 'site.wsgi' in the root directory of the virtual host, appears as being mounted on the root of the virtual host would be:

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

Do note however that when the WSGI application is executed for a request the 'SCRIPT_NAME' variable indicating what the mount point of the application was will be '/site.wsgi'. This will mean that when a WSGI application constructs an absolute URL based on 'SCRIPT_NAME', it will include 'site.wsgi' in the URL rather than it being hidden. As this would probably be undesirable, many web frameworks provide an option to override what the value for the mount point is. If such a configuration option isn't available, it is just as easy to adjust the value of 'SCRIPT_NAME' in the 'site.wsgi' script file itself.

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)

This wrapper will ensure that 'site.wsgi' never appears in the URL as long as it wasn't included in the first place and that access was always via the root of the web site instead.

关于python - 如何让apache在Flask webapp上提供静态文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31298755/

有关python - 如何让apache在Flask webapp上提供静态文件的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  4. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  5. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  6. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  7. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  8. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

随机推荐