Tornado RequestHandler和Application类
Tornado提供了一个具有异步功能的简单 Web 框架,允许它扩展到大量打开的连接,使其成为长轮询的理想选择。
这是一个简单的“Hello, world”示例应用程序:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", MainHandler),
])
application.listen(8888)
tornado.ioloop.IOLoop.current().start()
线路安全说明
一般来说,RequestHandler
和 Tornado 中其他地方的方法不是线程安全的。 特别是 write()
、finish()
和 flush()
等方法只能从主线程调用。 如果您使用多个线程,重要的是在完成请求之前使用 IOLoop.add_callback
将控制权转移回主线程,或者将其他线程的使用限制为 IOLoop.run_in_executor
并确保您在执行程序中运行的回调不引用 到 Tornado 对象。
请求处理程序
HTTP 请求处理程序的基类。
子类必须至少定义下面“入口点”部分中定义的方法之一。
应用程序不应直接构造 RequestHandler
对象,子类不应覆盖 __init__
(而是覆盖初始化)。
入口点
RequestHandler.initialize() → None
子类初始化的钩子,为每个请求调用。
作为 URLSpec 的第三个参数传递的字典将作为关键字参数提供给 initialize()。
示例如下:
class ProfileHandler(RequestHandler):
def initialize(self, database):
self.database = database
def get(self, username):
...
app = Application([
(r'/user/(.*)', ProfileHandler, dict(database=database)),
])
RequestHandler.prepare() → 可选项[Awaitable[None]]
在 get
/post
等之前的请求开始时调用。
覆盖此方法以执行通用初始化,而不管请求方法如何。
异步支持:使用 async def
或用 gen.coroutine
装饰此方法以使其异步。 如果此方法返回 Awaitable
,则在 Awaitable
完成之前不会继续执行。
3.1 版新功能:异步支持。
RequestHandler.on_finish() → None
在请求结束后调用。
重写此方法以执行清理、记录等。此方法是准备的对应方法。 on_finish
可能不会产生任何输出,因为它是在响应发送到客户端之后调用的。
实现以下任一方法(统称为 HTTP 动词方法)来处理相应的 HTTP 方法。 可以使用 async def
关键字或 gen.coroutine
使这些方法异步。
这些方法的参数来自 URLSpec
:正则表达式中的任何捕获组都将成为 HTTP 动词方法的参数(如果组被命名,则为关键字参数,如果未命名,则为位置参数)。
要支持不在此列表中的方法,请覆盖类变量 SUPPORTED_METHODS:
class WebDAVHandler(RequestHandler):
SUPPORTED_METHODS = RequestHandler.SUPPORTED_METHODS + ('PROPFIND',)
def propfind(self):
pass
输入
argument
方法提供对 HTML 表单样式参数的支持。 这些方法可用于单数和复数形式,因为 HTML 表单是模棱两可的,并且不区分单数参数和包含一个条目的列表。 如果您希望使用其他格式的参数(例如 JSON),请自己解析 self.request.body
:
def prepare(self):
if self.request.headers['Content-Type'] == 'application/x-json':
self.args = json_decode(self.request.body)
# Access self.args directly instead of using self.get_argument.
RequestHandler.get_argument(name: str, default: Union[None, str, RAISE] = RAISE, strip: bool = True) → Optional返回具有给定名称的请求 cookie 的值。
如果指定的 cookie 不存在,则返回默认值。
此方法仅返回请求中存在的 cookie。 它看不到由 set_cookie 在此处理程序中设置的传出 cookie。[str]
返回具有给定名称的参数的值。
如果未提供默认值,则认为该参数是必需的,如果缺少,将引发 MissingArgumentError
。
如果参数多次出现在请求中,我们返回最后一个值。
此方法搜索查询和正文参数。
RequestHandler.get_arguments(name: str, strip: bool = True) → List[str]
返回具有给定名称的参数列表。
如果参数不存在,则返回一个空列表。
此方法搜索查询和正文参数。
RequestHandler.get_query_argument(name: str, default: Union[None, str, RAISE] = RAISE, strip: bool = True) → Optional[str]
从请求查询字符串中返回具有给定名称的参数的值。
如果未提供默认值,则认为该参数是必需的,如果缺少,我们将引发 MissingArgumentError
。
如果参数多次出现在 url 中,我们返回最后一个值。
3.2 版中的新功能。
RequestHandler.get_query_arguments(name: str, strip: bool = True) → List[str]
返回具有给定名称的查询参数列表。
如果参数不存在,则返回一个空列表。
3.2 版中的新功能。
RequestHandler.get_body_argument(name: str, default: Union[None, str, RAISE] = RAISE, strip: bool = True) → Optional[str]
从请求正文返回具有给定名称的参数的值。
如果未提供默认值,则认为该参数是必需的,如果缺少,我们将引发 MissingArgumentError
。
如果参数多次出现在 url 中,我们返回最后一个值。
3.2 版中的新功能。
RequestHandler.get_body_arguments(name: str, strip: bool = True) → List[str]
返回具有给定名称的主体参数列表。
如果参数不存在,则返回一个空列表。
3.2 版中的新功能。
RequestHandler.decode_argument(value: bytes, name: Optional[str] = None) → str
从请求中解码参数。
该参数已被百分比解码,现在是一个字节字符串。 默认情况下,此方法将参数解码为 utf-8 并返回一个 unicode 字符串,但这可能在子类中被覆盖。
此方法用作 get_argument()
和从 url 中提取并传递给 get()
/post()
等值的过滤器。
如果已知,则提供参数的名称,但可以为 None(例如,对于 url 正则表达式中的未命名组)。
RequestHandler.request
tornado.httputil.HTTPServerRequest
对象包含其他请求参数,例如 标题和正文数据。
RequestHandler.path_kwargs
path_args
和 path_kwargs
属性包含传递给 HTTP 方法的位置和关键字参数。 这些属性是在调用这些方法之前设置的,因此这些值在准备期间可用。
输出
RequestHandler.set_status(status_code: int, reason: Optional[str] = None) → None
为我们的响应设置状态码。
参数:
-
status_code (int)
-- 响应状态代码。 -
reason (str)
-- 描述状态代码。 如果没有,它将从 http.client.responses 或“空”填写。
在 5.0 版更改: 不再验证响应代码是否在 http.client.responses
中。
RequestHandler.set_header(name: str, value: Union[bytes, str, int, numbers.Integral, datetime.datetime]) → None
设置给定的响应头名称和值。
所有标头值都转换为字符串(datetime
对象根据 Date
表头的 HTTP 规范进行格式化)。
RequestHandler.add_header(name: str, value: Union[bytes, str, int, numbers.Integral, datetime.datetime]) → None
添加给定的响应表头和值。
与 set_header
不同,add_header
可以被多次调用以返回同一个表头的多个值。
RequestHandler.clear_header(name: str) → None
清除传出标头,撤消先前的set_header
调用。
请注意,此方法不适用于 add_header
设置的多值表头。
RequestHandler.set_default_headers() → None
覆盖它以在请求开始时设置 HTTP 表头。
例如,这是设置自定义服务器表头的地方。 请注意,在请求处理的正常流程中设置此类表头可能无法满足您的要求,因为在错误处理期间可能会重置表头。
RequestHandler.write(chunk: Union[str, bytes, dict]) → None
将给定的块写入输出缓冲区。
要将输出写入网络,请使用下面的 flush()
方法。
如果给定的块是一个字典,我们将它写为 JSON 并将响应的 Content-Type
设置为 application/json
。 (如果您想将 JSON 作为不同的 Content-Type
发送,请在调用 write()
后调用 set_header
)。
请注意,由于潜在的跨站点安全漏洞,列表不会转换为 JSON。 所有 JSON 输出都应包含在字典中。
RequestHandler.flush(include_footers: bool = False) → Future[None]
将当前输出缓冲区刷新到网络。
在 4.0 版更改: 如果没有给出回调,现在返回 Future
。
在 6.0 版更改: 回调参数已删除。
RequestHandler.finish(chunk: Union[str, bytes, dict, None] = None) → Future[None]
完成此响应,结束 HTTP 请求。
将一个块传递给 finish()
等效于将该块传递给 write()
然后调用没有参数的 finish()
。
返回一个 Future
,它可以选择等待以跟踪向客户端发送的响应。 当所有响应数据都已发送时,此 Future
将解析,如果在发送所有数据之前关闭连接,则会引发错误。
在 5.1 版更改: 现在返回 Future
而不是 None
。
RequestHandler.render(template_name: str, **kwargs) → Future[None]
使用给定参数呈现模板作为响应。
render()
调用了 finish()
,因此在它之后不能调用其他输出方法。
返回一个与finish
返回的具有相同语义的Future
。 等待这个 Future
是可选的。
在 5.1 版更改: 现在返回 Future
而不是 None
。
RequestHandler.render_string(template_name: str, **kwargs) → bytes
使用给定的参数生成给定的模板。
我们返回生成的字节串(utf8 格式)。 要使生成和编写模板作为响应,请使用上面的 render()
。
RequestHandler.get_template_namespace() → Dict[str, Any]
返回要用作默认模板命名空间的字典。
可以被子类覆盖以添加或修改值。
此方法的结果将与 tornado.template
模块中的其他默认值和渲染或渲染字符串的关键字参数相结合。
RequestHandler.redirect(url: str, permanent: bool = False, status: Optional[int] = None) → None
将重定向发送到给定的(可选相对)URL。
如果指定了 status
参数,则该值用作 HTTP 状态代码; 否则根据永久参数选择 301(永久)或 302(临时)。 默认值为 302(临时)。
RequestHandler.send_error(status_code: int = 500, **kwargs) → None
将给定的 HTTP 错误代码发送到浏览器。
如果已经调用了 flush()
,则不可能发送错误,因此此方法将简单地终止响应。 如果输出已写入但尚未刷新,它将被丢弃并替换为错误页面。
覆盖 write_error()
以自定义返回的错误页面。 额外的关键字参数被传递给 write_error
。
RequestHandler.write_error(status_code: int, **kwargs) → None
覆盖以实现自定义错误页面。
write_error
可以像往常一样调用 write
、render
、set_header
等来产生输出。
如果此错误是由未捕获的异常(包括 HTTPError)引起的,则 exc_info
三元组将以 kwargs["exc_info"]
的形式提供。 请注意,对于 sys.exc_info()
或 traceback.format_exc
等方法而言,此异常可能不是“当前”异常。
RequestHandler.clear() → None
重置此响应的所有表头和内容。
RequestHandler.render_linked_js(js_files: Iterable[str]) → str
用于呈现已呈现网页的最终 js 链接的默认方法。
在子类控制器中覆盖此方法以更改输出。
RequestHandler.render_embed_js(js_embed: Iterable[bytes]) → bytes
用于渲染网页的最终嵌入 js 的默认方法。
在子类控制器中覆盖此方法以更改输出。
RequestHandler.render_linked_css(css_files: Iterable[str]) → str
用于呈现已呈现网页的最终 css 链接的默认方法。
在子类控制器中覆盖此方法以更改输出。
RequestHandler.render_embed_css(css_embed: Iterable[bytes]) → bytes
用于为渲染网页渲染最终嵌入 css 的默认方法。
在子类控制器中覆盖此方法以更改输出。
Cookies
RequestHandler.get_cookie(name: str, default: Optional[str] = None) → Optional[str]
返回具有给定名称的请求 cookie 的值。
如果指定的 cookie 不存在,则返回默认值。
此方法仅返回请求中存在的 cookie。 它看不到由 set_cookie
在此处理程序中设置的传出 cookie。
RequestHandler.set_cookie(name: str, value: Union[str, bytes], domain: Optional[str] = None, expires: Union[float, Tuple, datetime.datetime, None] = None, path: str = '/', expires_days: Optional[float] = None, **kwargs) → None
使用给定选项设置传出 cookie 名称/值。
新设置的 cookie 不会通过 get_cookie
立即可见; 他们直到下一个请求才会出现。
expires 可以是 time.time
返回的数字时间戳、time.gmtime
返回的时间元组或 datetime.datetime
对象。
额外的关键字参数直接在 cookies.Morsel 上设置。
RequestHandler.clear_cookie(name: str, path: str = '/', domain: Optional[str] = None) → None
删除具有给定名称的 cookie。
由于 cookie 协议的限制,您必须传递与设置 cookie 时使用的相同路径和域来清除 cookie(但无法在服务器端找出给定 cookie 使用了哪些值) .
和 set_cookie
类似,这个方法的效果要等到后面的请求才会看到。
RequestHandler.clear_all_cookies(path: str = '/', domain: Optional[str] = None) → None
删除用户随此请求发送的所有 cookie。
和 set_cookie
类似,这个方法的效果要等到后面的请求才会看到。
在 3.2 版更改: 添加了路径和域参数。
RequestHandler.get_secure_cookie(name: str, value: Optional[str] = None, max_age_days: float = 31, min_version: Optional[int] = None) → Optional[bytes]
如果验证通过,则返回给定的签名 cookie,或者无。
解码后的 cookie 值作为字节字符串返回(与 get_cookie
不同)。
与 get_cookie
类似,此方法仅返回请求中存在的 cookie。 它在此处理程序中看不到由 set_secure_cookie
设置的传出 cookie。
在 3.2.1 版更改:添加了 min_version
参数。 引入 cookie 版本 2; 默认情况下接受版本 1 和 2。
RequestHandler.get_secure_cookie_key_version(name: str, value: Optional[str] = None) → Optional[int]
返回安全 cookie 的签名密钥版本。
版本以 int 形式返回。
RequestHandler.set_secure_cookie(name: str, value: Union[str, bytes], expires_days: Optional[float] = 30, version: Optional[int] = None, **kwargs) → None
对 cookie 进行签名和时间戳记,使其无法被伪造。
您必须在应用程序中指定 cookie_secret
设置才能使用此方法。 它应该是一个长的、随机的字节序列,用作签名的 HMAC 机密。
要使用此方法读取 cookie 集,请使用 get_secure_cookie()
。
请注意 expires_days
参数设置浏览器中 cookie 的生命周期,但与 get_secure_cookie
的 max_age_days
参数无关。 None 值将生命周期限制为当前浏览器会话。
安全 cookie 可能包含任意字节值,而不仅仅是 unicode 字符串(与常规 cookie 不同)
和 set_cookie
类似,这个方法的效果要等到后面的请求才会看到。
在 3.2.1 版更改:添加了version
参数。 引入 cookie 版本 2 并将其设为默认值。
RequestHandler.create_signed_value(name: str, value: Union[str, bytes], version: Optional[int] = None) → bytes
对字符串进行签名和时间戳记,使其不能被伪造。
通常通过 set_secure_cookie
使用,但作为非 cookie 使用的单独方法提供。 要解码未存储为 cookie 的值,请使用 get_secure_cookie
的可选值参数。
在 3.2.1 版更改:添加了version
参数。 引入 cookie 版本 2 并将其设为默认值。
应用程序配置
构成 Web 应用程序的请求处理程序的集合。
此类的实例是可调用的,并且可以直接传递给 HTTPServer 以服务于应用程序:
application = web.Application([
(r"/", MainPageHandler),
])
http_server = httpserver.HTTPServer(application)
http_server.listen(8080)
ioloop.IOLoop.current().start()
此类的构造函数接收一个 Rule
对象列表或对应于 Rule
构造函数参数的值元组:(matcher, target, [target_kwargs], [name])
,方括号中的值是可选的。 默认匹配器是 PathMatches
,因此也可以使用 (regexp, target)
元组来代替 (PathMatches(regexp), target)
。
常见的路由目标是 RequestHandler
子类,但您也可以使用规则列表作为目标,从而创建嵌套路由配置:
application = web.Application([
(HostMatches("example.com"), [
(r"/", MainPageHandler),
(r"/feed", FeedHandler),
]),
])
除此之外,您还可以使用嵌套的 Router
实例、HTTPMessageDelegate
子类和可调用对象作为路由目标。
当我们收到请求时,我们按顺序遍历列表并实例化第一个请求类的实例,其正则表达式与请求路径匹配。 请求类可以指定为类对象或(完全限定的)名称。
字典可以作为元组的第三个元素 (target_kwargs
) 传递,它将用作处理程序的构造函数和initialize
方法的关键字参数。 此模式用于本示例中的 StaticFileHandler
(请注意,可以使用下面描述的 static_path
设置自动安装 StaticFileHandler
):
application = web.Application([
(r"/static/(.*)", web.StaticFileHandler, {"path": "/var/www"}),
])
我们使用 add_handlers
方法支持虚拟主机(virtual hosts),该方法将主机的正则表达式作为第一个参数:
application.add_handlers(r"www\.myhost\.com", [
(r"/article/([0-9]+)", ArticleHandler),
])
如果当前请求的主机不匹配,则 default_host
参数值与主机的正则表达式匹配。
注意:不使用 TLS 的应用程序可能容易受到 DNS 重新绑定攻击。 此攻击与仅侦听 127.0.0.1
或其他专用网络的应用程序特别相关。 必须使用适当的主机模式(而不是默认的 r'.*'
)来防止这种风险。 default_host
参数不得用于可能易受 DNS 重新绑定攻击的应用程序中。
您可以通过将 static_path
设置作为关键字参数发送来提供静态文件。 我们将从 /static/ URI
提供这些文件(这可以通过 static_url_prefix
设置进行配置),我们将从同一目录提供 /favicon.ico
和 /robots.txt
。 可以使用 static_handler_class
设置指定 StaticFileHandler
的自定义子类。
在 4.5 版更改: 与新的 tornado.routing
模块集成。
Application.listen(port: int, address: str = '', **kwargs) → tornado.httpserver.HTTPServer
在给定端口上为此应用程序启动 HTTP 服务器。
这是一个方便的别名,用于创建HTTPServer
对象并调用其监听方法。 HTTPServer.listen
不支持的关键字参数被传递给 HTTPServer
构造函数。 对于高级用途(例如多进程模式),请勿使用此方法; 创建一个 HTTPServer
并直接调用它的 TCPServer.bind/TCPServer.start
方法。
请注意,调用此方法后,您仍然需要调用 IOLoop.current().start()
来启动服务器。
返回 HTTPServer
对象。
Application.add_handlers(handlers: List[Union[Rule, Tuple]])
将给定的处理程序附加到我们的处理程序列表中。
主机模式按照添加的顺序依次处理, 将考虑所有匹配模式。
Application.get_handler_delegate(request: tornado.httputil.HTTPServerRequest, target_class: Type[tornado.web.RequestHandler], target_kwargs: Optional[Dict[str, Any]] = None, path_args: Optional[List[bytes]] = None, path_kwargs: Optional[Dict[str, bytes]] = None) → tornado.web._HandlerDelegate
返回可以为应用程序和 RequestHandler
子类提供请求的 HTTPMessageDelegate
。
参数:
-
request
(httputil.HTTPServerRequest) – 当前的 HTTP 请求。 -
target_class
(RequestHandler) – 一个 RequestHandler 类。 -
target_kwargs
(dict) -- target_class 构造函数的关键字参数。 -
path_args
(list) – target_class HTTP 方法的位置参数,将在处理请求(get、post 或任何其他)时执行。 -
path_kwargs
(dict) -- target_class HTTP 方法的关键字参数。
Application.reverse_url(name: str, *args) → str
返回名为 name 的处理程序的 URL 路径
该处理程序必须作为命名的 URLSpec
添加到应用程序中。
Args 将替换 URLSpec
正则表达式中的捕获组。 如有必要,它们将被转换为字符串,编码为 utf8 并转义 url。
Application.log_request(handler: tornado.web.RequestHandler) → None
将完成的 HTTP 请求写入日志。
默认情况下写入 python 根记录器。 要更改此行为,请继承 Application 并覆盖此方法,或将应用程序设置字典中的函数作为 log_function
传递。
class tornado.web.URLSpec(pattern: Union[str, Pattern[AnyStr]], handler: Any, kwargs: Optional[Dict[str, Any]] = None, name: Optional[str] = None)
指定 URL 和处理程序之间的映射。
参数:
-
pattern
:要匹配的正则表达式。 正则表达式中的任何捕获组都将作为参数传递给处理程序的 get/post等方法(如果命名则按关键字,如果未命名则按位置。命名和未命名的捕获组不能在同一规则中混合使用)。 -
handler
:要调用的 RequestHandler 子类。 -
kwargs
(可选):要传递给处理程序构造函数的附加参数字典。 -
name
(可选):此处理程序的名称, 由 reverse_url
使用。
URLSpec
类也可以在名称 tornado.web.url
下使用。