web-dev-qa-db-ja.com

Tornadoでindex.htmlを処理するためのより良い方法はありますか?


トルネードで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()
17

TornadoのStaticFileHandlerにはすでにデフォルトのファイル名機能が含まれていることがわかりました。

Tornadoリリース1.2.0で機能が追加されました: https://github.com/tornadoweb/tornado/commit/638a151d96d681d3bdd6ba5ce5dcf2bd1447959c

デフォルトのファイル名を指定するには、WebStaticFileHandler初期化の一部として「default_filename」パラメーターを設定する必要があります。

例の更新:

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
23
Adaptation

前の答えのおかげで、これが私が好む解決策です:

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')
12

代わりにこのコードを使用してください

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)

アプリケーションでVanillaStaticFileHandlerの代わりにそのクラスを使用するようになりました...ジョブは完了です!

5
Mike H

私はこれを試してきました。レンダリングを使用しないでください。テンプレートを解析するオーバーヘッドが追加され、静的htmlのテンプレートタイプの文字列でエラーが発生します。これが最も簡単な方法だと思いました。トルネードは正規表現でキャプチャ括弧を探しています。空のキャプチャグループを指定してください。

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のような不要な解決も回避します。

4
dark knight

StaticFileHandlerを明示的に追加する必要はありません。 static_pathを指定するだけで、それらのページが提供されます。

URLにファイル名を追加しても、何らかの理由でTornadoがindex.htmlファイルを提供しないため、MainHandlerが必要であることは正しいです。

その場合、コードにこのわずかな変更を加えるだけでうまくいくはずです。

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()
4
Wesley Baugh

これは私のために働いた 竜巻のドキュメントから

ディレクトリが要求されたときに_index.html_のようなファイルを自動的に提供するには、アプリケーション設定でstatic_handler_args=dict(default_filename="index.html")を設定するか、StaticFileHandlerの初期化引数として_default_filename_を追加します。

0
user3594056