Есть ли лучший способ обрабатывать index.html с Tornado? - программирование
Подтвердить что ты не робот

Есть ли лучший способ обрабатывать index.html с Tornado?


Я хочу знать, есть ли лучший способ обработать файл index.html с помощью Tornado.

Я использую 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()
4b9b3361

Ответ 1

Оказывается, что 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()

Это обрабатывает запросы root:

  • //index.html

запросы подкаталогов:

  • /tests//tests/index.html

и, похоже, правильно обрабатывает перенаправления для каталогов, что приятно:

  • /tests/tests/index.html

Ответ 2

Благодаря предыдущему ответу, вот решение, которое я предпочитаю:

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()

И Settings.py

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

STATIC_PATH = os.path.join(dirname, 'static')
TEMPLATE_PATH = os.path.join(dirname, 'templates')

Ответ 3

Используйте этот код вместо

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 в вашем приложении... работа выполнена!

Ответ 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()

Ответ 5

Я пытался это сделать. Не используйте рендер, у которого есть дополнительные накладные расходы на шаблоны синтаксического анализа и дает ошибку в строках типа шаблона в статическом html. Я нашел, что это самый простой способ. Tornado ищет скобку в регулярном выражении, просто дайте ей пустую группу захвата.

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

Ответ 6

Это сработало для меня Из торнадо-документов:

Чтобы автоматически подать файл типа index.html при запросе каталога, установите static_handler_args=dict(default_filename="index.html") в настройках вашего приложения или добавьте default_filename в качестве аргумента инициализатора для StaticFileHandler.