我想知道是否有更好的方法来处理带有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()
答案 0 :(得分:22)
事实证明,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
答案 1 :(得分: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()
和Settings.py
import os
dirname = os.path.dirname(__file__)
STATIC_PATH = os.path.join(dirname, 'static')
TEMPLATE_PATH = os.path.join(dirname, 'templates')
答案 2 :(得分: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 ...工作完成了!
答案 3 :(得分:4)
无需明确添加StaticFileHandler
;只需指定static_path,它就会为这些页面提供服务。
你是正确的,你需要一个MainHandler,因为某些原因,即使你将文件名附加到URL,Tornado也不会提供index.html
文件。
在这种情况下,对代码的这种轻微修改应该适合您:
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 :(得分:4)
我一直在尝试这个。不要使用渲染,它有额外的解析模板的开销,并在静态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
答案 5 :(得分:-1)
这对我有用From the tornado docs:
要在请求目录时自动提供
index.html
这样的文件,请在应用程序设置中设置static_handler_args=dict(default_filename="index.html")
,或将default_filename
添加为StaticFileHandler
的初始化参数。