Flask中的静态文件-robot.txt,sitemap.xml(mod_wsgi)


94

是否有任何聪明的解决方案将静态文件存储在Flask的应用程序根目录中。robots.txt和sitemap.xml有望在/中找到,所以我的想法是为它们创建路由:

@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
  response = make_response(open('sitemap.xml').read())
  response.headers["Content-type"] = "text/plain"
  return response

必须有一些更方便的方法:)

Answers:


78

最好的方法是将static_url_path设置为root url

from flask import Flask

app = Flask(__name__, static_folder='static', static_url_path='')

值得一提的是,static_folder不必位于项目文件夹中。例如static_folder ='/ app / ui'很好。
Ashic

66

@vonPetrushev是正确的,在生产中,您将希望通过nginx或apache提供静态文件,但是对于开发人员来说,最好让开发环境简单,让python应用程序也提供静态内容,因此您不必担心有关更改配置和多个项目的信息。为此,您将要使用SharedDataMiddleware

from flask import Flask
app = Flask(__name__)
'''
Your app setup and code
'''
if app.config['DEBUG']:
    from werkzeug import SharedDataMiddleware
    import os
    app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
      '/': os.path.join(os.path.dirname(__file__), 'static')
    })

本示例假定您的静态文件位于文件夹“ static”中,并根据您的环境进行调整。


1
谢谢!这就是我所需要的!我正在为我的生产heroku做到这一点。请参见以下线程的答案:flask.pocoo.org/mailinglist/archive/2012/2/22/…– 2012
大卫

2
注意-现在有一种更简单的方法来处理此问题。查看我的回复。
肖恩·麦克索明

1
有没有一种方法可以使SharedDataMiddleware将'/'解析为index.html或类似内容?
gromgull

63

这个问题的最干净答案是这个(相同)问题答案

from flask import Flask, request, send_from_directory
app = Flask(__name__, static_folder='static')    

@app.route('/robots.txt')
@app.route('/sitemap.xml')
def static_from_root():
    return send_from_directory(app.static_folder, request.path[1:])

总结一下:

  • 正如David指出的那样,通过正确的配置,可以通过prod提供一些静态文件
  • 查找/robots.txt不应导致重定向到/static/robots.txt。(在肖恩斯回答中,目前尚不清楚如何实现。)
  • 将静态文件添加到应用程序根文件夹中并不干净
  • 最后,所提出的解决方案看起来比添加中间件方法更干净:

22

尽管这是一个古老的答案问题,但我正在回答这个问题,因为此帖子在Google搜索结果中的排名很高。尽管文档中未涉及它,但是如果您阅读了Flask Application对象构造函数的API文档,则将涉及它。通过static_folder像这样传递命名参数:

from flask import Flask
app = Flask(__name__,
            static_folder="/path/to/static",
            template_folder="/path/to/templates")

...您可以定义从何处提供静态文件。同样,您可以定义a template_folder,即您的名字static_url_path


@chmike是的,它默认为,/static但是您可以通过覆盖来更改它static_url_path
肖恩·麦克索明

这是正确的,但其他答案更为灵活。这一限制是因为它只能服务一个目录路径。
Thomas Dignan

这不是原始问题的答案。
Paolo Casciello

2
如果将static_url_path设置为“”,则可以从/提供文件。

这迫使Flask提供静态文件。如果您希望Nginx或Apache为他们服务怎么办?
Markon 2013年

15

提供静态文件与旨在传递动态内容的应用程序无关。提供静态文件的正确方法取决于您使用的服务器。毕竟,当您启动并运行应用程序时,需要将其绑定到Web服务器。我只能说Apache httpd,因此在通过mod-wsgi绑定到应用程序的虚拟主机中定义了提供静态文件的方式。以下指南将向您展示如何提供站点地图,robots.txt或任何静态内容:http : //code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site


这就是我一直在寻找的答案。谢谢!
biesiad 2010年

1
应用程序旨在交付内容,其中包括动态内容和静态内容。
Dem Pilafian

14

发送静态文件的另一种方法是使用全部规则,如下所示:

@app.route('/<path:path>')
def catch_all(path):
    if not app.debug:
        flask.abort(404)
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    return f.read()

我用它来尽量减少开发时的设置。我从http://flask.pocoo.org/snippets/57/获得了这个想法

此外,我正在单机上使用flask开发,但在生产服务器中使用Apache进行了部署。我用:

file_suffix_to_mimetype = {
    '.css': 'text/css',
    '.jpg': 'image/jpeg',
    '.html': 'text/html',
    '.ico': 'image/x-icon',
    '.png': 'image/png',
    '.js': 'application/javascript'
}
def static_file(path):
    try:
        f = open(path)
    except IOError, e:
        flask.abort(404)
        return
    root, ext = os.path.splitext(path)
    if ext in file_suffix_to_mimetype:
        return flask.Response(f.read(), mimetype=file_suffix_to_mimetype[ext])
    return f.read()

[...]

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-d', '--debug', dest='debug', default=False,
                      help='turn on Flask debugging', action='store_true')

    options, args = parser.parse_args()

    if options.debug:
        app.debug = True
        # set up flask to serve static content
        app.add_url_rule('/<path:path>', 'static_file', static_file)
    app.run()

1
注意-现在有一种更简单的方法来处理此问题。查看我的回复。
肖恩·麦克索明

如果您需要服务多条路径,这是绝佳的方式!
Thomas Dignan

6

自从问了这个问题以来,可能已经添加了它,但是我正在查看flask的“ helpers.py”,然后发现flask.send_from_directory:

send_from_directory(directory, filename, **options)
'''
  send_from_directory(directory, filename, **options)
  Send a file from a given directory with send_file.  This
  is a secure way to quickly expose static files from an upload folder
  or something similar.
'''

...引用flask.send_file:

send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False)

...尽管对send_from_directory直接传递** options到send_file,但似乎可以更好地进行控制。


3

从此处的文档中:http : //flask.pocoo.org/docs/quickstart/#static-files

动态Web应用程序也需要静态文件。通常这就是CSS和JavaScript文件的来源。理想情况下,将Web服务器配置为为您提供服务,但是在开发过程中Flask也可以做到。只需在包中或模块旁边创建一个名为static的文件夹,该文件夹将在应用程序的/ static中可用。

要生成指向该URL部分的URL,请使用特殊的“静态” URL名称:

url_for('静态',filename ='style.css')

该文件必须以static / style.css的形式存储在文件系统中。


0

我也有同样的困境。做了一些搜索,找到了我的答案(MHO):

也可以从文档中引用

动态Web应用程序也需要静态文件。通常这就是CSS和JavaScript文件的来源。理想情况下,您的Web服务器配置为可以为您提供服务,但是在开发期间Flask也可以做到。只需在包中或模块旁边创建一个名为static的文件夹,该文件夹将在应用程序的/ static中可用。

恕我直言:当您的应用程序投入生产时,应在Web服务器(nginx,apache)上配置(或理想情况下)静态文件服务;但是在开发过程中,Flask使其可用于提供静态文件。这是为了帮助您快速发展-无需设置网络服务器等。

希望能帮助到你。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.