19


我想知道是否有更好的方法来使用 Tornado 处理我的 index.html 文件。

我对所有请求都使用 StaticFileHandler,并使用特定的 MainHandler 来处理我的主要请求。如果我只使用 StaticFileHandler 我得到一个 403: Forbidden 错误

GET http://localhost:9000/
WARNING:root:403 GET / (127.0.0.1):  is not a file

我现在怎么做:

import os
import tornado.ioloop
import tornado.web
from  tornado import web

__author__ = 'gvincent'

root = os.path.dirname(__file__)
port = 9999

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        try:
            with open(os.path.join(root, 'index.html')) as f:
                self.write(f.read())
        except IOError as e:
            self.write("404: Not Found")

application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/(.*)", web.StaticFileHandler, dict(path=root)),
    ])

if __name__ == '__main__':
    application.listen(port)
    tornado.ioloop.IOLoop.instance().start()
4

6 回答 6

28

事实证明,Tornado 的 StaticFileHandler 已经包含默认文件名功能。

在 Tornado 版本 1.2.0 中添加了功能: https ://github.com/tornadoweb/tornado/commit/638a151d96d681d3bdd6ba5ce5dcf2bd1447959c

要指定默认文件名,您需要将“default_filename”参数设置为 WebStaticFileHandler 初始化的一部分。

更新您的示例:

import os
import tornado.ioloop
import tornado.web

root = os.path.dirname(__file__)
port = 9999

application = tornado.web.Application([
    (r"/(.*)", tornado.web.StaticFileHandler, {"path": root, "default_filename": "index.html"})
])

if __name__ == '__main__':
    application.listen(port)
    tornado.ioloop.IOLoop.instance().start()

这处理根请求:

  • /->/index.html

子目录请求:

  • /tests/->/tests/index.html

并且似乎可以正确处理目录的重定向,这很好:

  • /tests->/tests/index.html
于 2015-01-11T19:47:30.130 回答
12

感谢上一个答案,这是我更喜欢的解决方案:

import Settings
import tornado.web
import tornado.httpserver


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler)
        ]
        settings = {
            "template_path": Settings.TEMPLATE_PATH,
            "static_path": Settings.STATIC_PATH,
        }
        tornado.web.Application.__init__(self, handlers, **settings)


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")


def main():
    applicaton = Application()
    http_server = tornado.httpserver.HTTPServer(applicaton)
    http_server.listen(9999)

    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

和设置.py

import os
dirname = os.path.dirname(__file__)

STATIC_PATH = os.path.join(dirname, 'static')
TEMPLATE_PATH = os.path.join(dirname, 'templates')
于 2013-04-16T08:51:31.043 回答
5

请改用此代码

class IndexDotHTMLAwareStaticFileHandler(tornado.web.StaticFileHandler):
    def parse_url_path(self, url_path):
        if not url_path or url_path.endswith('/'):
            url_path += 'index.html'

        return super(IndexDotHTMLAwareStaticFileHandler, self).parse_url_path(url_path)

现在在您的应用程序中使用该类而不是 vanilla StaticFileHandler ... 工作完成!

于 2014-05-22T23:46:26.733 回答
4

无需显式添加StaticFileHandler; 只需指定 static_path ,它将为这些页面提供服务。

您需要一个 MainHandler 是正确的,因为由于某种原因 Tornado 不会提供该index.html文件,即使您将文件名附加到 URL 也是如此。

在这种情况下,对您的代码的这种轻微修改应该适合您:

import os
import tornado.ioloop
import tornado.web
from tornado import web

__author__ = 'gvincent'

root = os.path.dirname(__file__)
port = 9999

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("index.html")

application = tornado.web.Application([
    (r"/", MainHandler),
    ], template_path=root,
    static_path=root)

if __name__ == '__main__':
    application.listen(port)
    tornado.ioloop.IOLoop.instance().start()
于 2013-01-18T02:56:05.930 回答
4

我一直在尝试这个。不要使用渲染它会增加解析模板的开销,并且会在静态 html 中的模板类型字符串上报错。我发现这是最简单的方法。Tornado 正在 regex 中寻找一个捕获括号,只需给它一个空的捕获组。

import os
import tornado.ioloop
import tornado.web

root = os.path.dirname(__file__)
port = 9999

application = tornado.web.Application([
    (r"/()", tornado.web.StaticFileHandler, {"path": root, "default_filename": "index.html"})
])

这具有将 / 解析为 index.html 的效果,并且还避免了不需要的解析,例如 /views.html 到 static_dir/views.html

于 2015-06-24T04:52:45.087 回答
0

这对我有用来自龙卷风文档

index.html在请求目录时自动提供文件,请static_handler_args=dict(default_filename="index.html")在您的应用程序设置中设置,或添加default_filename为您的StaticFileHandler.

于 2016-03-09T17:02:22.207 回答