Python Web服务器Tornado使用小结

2019-10-06 16:08:55王旭

            self.render('500.html')
        else:
            super(RequestHandler, self).write_error(status_code, **kwargs)
由于历史原因,你也可以覆盖 get_error_html() 方法,不过不被推荐。
此外,你还可能没到 _execute() 方法就出错了。
例如 initialize() 方法抛出了一个未捕捉的异常,这个异常会被 IOStream 捕捉到,然后直接关闭连接,不能向用户输出任何错误页面。
再比如没有找到一个能处理该请求的 handler,就会用 tornado.web.ErrorHandler 去处理 404 错误。这种情况可以替换这个类来实现自定义错误页面:
class PageNotFoundHandler(RequestHandler):
    def get(self):
        raise tornado.web.HTTPError(404)

tornado.web.ErrorHandler = PageNotFoundHandler
另一种方法就是在 Application 的 handlers 参数的最后,加上一个能捕捉任何 URL 的 handler:
application = tornado.web.Application([
    # ...
    ('.*', PageNotFoundHandler)
])


四、接着说说处理登录。

Tornado 提供了 @tornado.web.authenticated 这个装饰器,在 handler 的 get() 等方法前加上即可。
它会依赖三处代码:
需要定义 handler 的 get_current_user() 方法,例如:
def get_current_user(self):
    return self.get_secure_cookie('user_id', 0)
它的返回值为假时,就会跳转到登录页面了。
创建 application 时设置 login_url 参数:
application = tornado.web.Application(
    [
        # ...
    ],
    login_url = '/login'
)
定义 handler 的 get_login_url() 方法。
如果不能使用默认的 login_url 参数(例如普通用户和管理员需要不同的登录地址),那么可以覆盖 get_login_url() 方法:
class AdminHandler(RequestHandler):
    def get_login_url(self):
        return '/admin/login'
顺带一提,跳转到登录页后时会附带一个 next 参数,指向登录前访问的网址。为达到更好的用户体验,需要在登录后跳转到该网址:
class LoginHandler(RequestHandler):
    def get(self):
        if self.get_current_user():
            self.redirect('/')
            return
        self.render('login.html')

    def post(self):
        if self.get_current_user():
            raise tornado.web.HTTPError(403)