Python 有没有更好的方法用 Tornado 处理 index.html?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14385048/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:15:41  来源:igfitidea点击:

is there a better way to handle index.html with Tornado?

pythontornado

提问by Guillaume Vincent


I want to know if there is a better way to handle my index.html file with Tornado.


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

I use StaticFileHandler for all the request,and use a specific MainHandler to handle my main request. If I only use StaticFileHandler I got a 403: Forbidden error

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

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

here how I doing now:

这里我现在怎么做:

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

采纳答案by Adaptation

Turns out that Tornado's StaticFileHandler already includes default filenamefunctionality.

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

Feature was added in Tornado release 1.2.0: https://github.com/tornadoweb/tornado/commit/638a151d96d681d3bdd6ba5ce5dcf2bd1447959c

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

To specify a default file name you need to set the "default_filename" parameter as part of the WebStaticFileHandler initialization.

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

Updating your example:

更新您的示例:

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

This handles root requests:

这处理根请求:

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

sub-directory requests:

子目录请求:

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

and appears to correctly handle redirects for directories, which is nice:

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

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

回答by Wesley Baugh

There is no need to explicitly add a StaticFileHandler; just specify the static_path and it will serve those pages.

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

You are correct that you need a MainHandler, as for some reason Tornado will not serve the index.htmlfile, even if you append the filename to the URL.

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

In that case, this slight modification to your code should work for you:

在这种情况下,对您的代码进行的这种轻微修改应该对您有用:

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

回答by Guillaume Vincent

Thanks to the previous answer, here is the solution I prefer:

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

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

And Settings.py

和 Settings.py

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

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

回答by Mike H

Use this code instead

改用此代码

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)

now use that class instead of vanilla StaticFileHandler in your Application... job's done!

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

回答by dark knight

I have been trying this. Don't use render it has additional overhead of parsing templates and gives error on template type strings in static html. I found this is the simplest way. Tornado is looking for a capturing parenthesis in regex , just give it an empty capturing group.

我一直在尝试这个。不要使用 render 它有额外的解析模板开销,并在静态 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"})
])

This has effect of resolving / to index.html and also avoid unwanted resolves like /views.html to static_dir/views.html

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

回答by user3594056

This worked for me From the tornado docs:

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

To serve a file like index.htmlautomatically when a directory is requested, set static_handler_args=dict(default_filename="index.html")in your application settings, or add default_filenameas an initializer argument for your StaticFileHandler.

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