分享
分享赚钱 收藏 举报 版权申诉 / 32

类型tornado中文教程.pdf

  • 上传人:HR专家
  • 文档编号:6299221
  • 上传时间:2019-04-05
  • 格式:PDF
  • 页数:32
  • 大小:283.04KB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    tornado中文教程.pdf
    资源描述:

    1、 概览 Overview 下载和安装 模块索引 o 主要模块 o 底层模块 Tornado 攻略 o 请求处理程序和请求 参 数 o 重写 RequestHandler 的方法函数 o 重定向(redirect) o 模板 o Cookie 和安全 Cookie o 用户认证 o 跨站伪造请求的防范 o 静态文件和主动式文 件 缓存 o 本地化 o UI 模块 o 非阻塞式异步请求 o 异步 HTTP 客户端 o 第三方认证 o 调试模式和自动重载 性能 生产环境下的部署 WSGI 和 Google AppEngine 注意事项和社区支持 Overview FriendFeed 使用了一款 使

    2、用 Python 编写的, 相对简单的 非阻塞 式 Web 服务器。 其应用程序使用的 Web 框架看起来有些像 web.py 或者 Google 的 webapp , 不 过为了能有效利用非 阻 塞式服务器环境,这 个 Web 框架还包含 了一些 相关的有用 工具 和优化。 Tornado 就是我们在 FriendFeed 的 Web 服务 器及其常用工具的开 源 版本。 Tornado 和现在的主流 Web 服务器框架 (包 括大多数 Python 的框 架) 有着明显 的区别: 它是非 阻塞式 服务器, 而且速 度相当 快。 得利于其 非阻塞的 方式和对 epoll 的运用,Tornad

    3、o 每秒 可以处理数以千计的 连 接,因此 Tornado 是实时 Web 服 务的一个 理想框架 。我 们开发这个 Web 服务 器的主要目的就是为 了 处理 FriendFeed 的实时功能 在 FriendFeed 的应用里每一个活动用 户 都会保持着 一个服务器连接 。 (关于 如何扩容 服务器 , 以处 理数以千计的客户端 的 连接的问题, 请参阅 The C10K problem ) 以下是经典的 “Hello, world” 示例: import tornado.ioloop import tornado.web class MainHandler(tornado.web.Req

    4、uestHandler): def get(self): self.write(“Hello, world“) application = tornado.web.Application( (r“/“, MainHandler), ) if _name_ = “_main_“: application.listen(8888) tornado.ioloop.IOLoop.instance().start() 查看下面的 Tornado 攻略 以了解更多关于 tornado.web 包 的细节。 我们清理了 Tornado 的基础代码,减少了 各 模块之间的相互依存 关 系,所以理论 上讲, 你

    5、可以在自 己的 项目中独立地使用任 何 模块,而不需要使用 整 个包。 下载和安装 自动 安装: Tornado 已 经列入 PyPI ,因此可以 通过 pip 或者 easy_install 来安 装。如果你没有安装 libcurl 的话,你需要将其 单独安装到系统中。 请 参见下面的 安装依赖一节。 注意一 点, 使用 pip 或 easy_install 安装的 Tornado 并没有包含 源代码中的 demo 程序 。 手动 安装: 下载 tornado-1.2.1.tar.gz tar xvzf tornado-1.2.1.tar.gz cd tornado-1.2.1 python

    6、 setup.py build sudo python setup.py install Tornado 的代码托管在 GitHub 上面。对于 Python 2.6 以 上的版本, 因为标准库 中已经包括了对 epoll 的支持,所以你可以 不 用 setup.py 编译安装, 只要简单地 将 tornado 的目录添加 到 PYTHONPATH 就可以使用了。 安装需 求 Tornado 在 Python 2.5, 2.6, 2.7 中都 经过了测 试。要使用 Tornado 的所有功能, 你需要安装 PycURL (7.18.2 或更高版本) 以及 simplejson (仅适用于Pyt

    7、hon 2.5, 2.6 以后的版本标 准库 当中已经包含了对 JSON 的支持)。为 方便起见 ,下面将列 出 Mac OS X 和 Ubuntu 中的完整安装方式: Mac OS X 10.6 (Python 2.6+) sudo easy_install setuptools pycurl Ubuntu Linux (Python 2.6+) sudo apt-get install python-pycurl Ubuntu Linux (Python 2.5) sudo apt-get install python-dev python-pycurl python-simplejson

    8、 模块索引 最重要的一个模块是web, 它就是包含了 Tornado 的大部分主要功 能的 Web 框 架。其它的模块都是 工 具性质的, 以便让 web 模块更加有用 后面 的 Tornado 攻 略 详细讲解了 web 模块 的使用方法。 主要模 块 web - FriendFeed 使用的基础 Web 框架 ,包 含了 Tornado 的大多 数 重要的功能 escape - XHTML, JSON, URL 的编 码/解码方 法 database - 对 MySQLdb 的简单封装,使其更 容 易使用 template - 基于 Python 的 web 模板 系统 httpclien

    9、t - 非阻塞式 HTTP 客户端,它被设 计用来 和 web 及 httpserver 协同工作 auth - 第三方认证的实 现(包括 Google OpenID/OAuth 、Facebook Platform 、Yahoo BBAuth 、FriendFeed OpenID/OAuth 、Twitter OAuth ) locale - 针对本地化和 翻译的支持 options - 命令行和配 置文件解析工具,针 对 服务器环境做了优化 底层模 块 httpserver - 服务于 web 模块的一个非常简单 的 HTTP 服务器的实 现 iostream - 对非阻塞式 的 sock

    10、et 的简单封装 ,以方便常用读写操 作 ioloop - 核心的 I/O 循环 Tornado 攻略 请 求处 理程 序和 请求 参数 Tornado 的 Web 程序 会将 URL 或者 URL 范式映射 到 tornado.web.RequestHandler 的子类上去。 在其子类中定义了 get() 或 post() 方法,用以处理不同的 HTTP 请求。 下面的代码将 URL 根目录 / 映射到 MainHandler,还将一个 URL 范 式 /story/(0-9+) 映射到 StoryHandler。正则表达式匹配的分组 会 作为参数引 入 的相应方法中: class Mai

    11、nHandler(tornado.web.RequestHandler): def get(self): self.write(“You requested the main page“) class StoryHandler(tornado.web.RequestHandler): def get(self, story_id): self.write(“You requested the story “ + story_id) application = tornado.web.Application( (r“/“, MainHandler), (r“/story/(0-9+)“, Sto

    12、ryHandler), ) 你可以使用 get_argument() 方法来获取查询字 符串参数,以及解析 POST 的内容: class MainHandler(tornado.web.RequestHandler): def get(self): self.write( ) def post(self): self.set_header(“Content-Type“, “text/plain“) self.write(“You wrote “ + self.get_argument(“message“) 上传的文件可以通过 self.request.files 访问到,该对象将名称(HTM

    13、L 元 素 的 name 属性)对应 到一个文件列表。每 一 个文件都以 字典的形式 存在, 其格 式为 “filename“:., “content_type“:., “body“:.。 如果你想要返回一个 错 误信息给客户端,例 如“403 unauthorized”,只需要抛出一 个 tornado.web.HTTPError 异常: if not self.user_is_logged_in(): raise tornado.web.HTTPError(403) 请求处理程序可以通 过 self.request 访问到代表当前请求的对象。 该 HTTPRequest 对象包含了一些有用

    14、的属性 , 包括: arguments - 所有的 GET 或 POST 的参数 files - 所有通过 multipart/form-data POST 请求上传的文件 path - 请求的路径( ? 之前的所有内容) headers - 请求的开头 信息 你可以通过查看源代 码 httpserver 模组中 HTTPRequest 的定义,从而 了解到它的 所有属性。 重写 RequestHandler 的方法函数 除了 get()/post()等以 外,RequestHandler 中 的一些别的方法函数 , 这都是 一些 空函数,它们存在的 目 的是在必要时在子类 中 重新定义其内容

    15、。对 于 一个请求的处 理 的代码调用次序 如下 : 1. 程序为每一个请求创 建 一个 RequestHandler 对象 2. 程序调用 initialize() 函数,这个函数 的参数 是 Application 配置中 的关键字 参数定义 。(initialize 方法是 Tornado 1.1 中新添加的, 旧版本中你需要 重写 _init_ 以达到同样的 目的) initialize 方法 一般只是把传入的参 数 存 到成员变量中, 而不 会产生一些输出或者 调 用像 send_error 之类的方法。 3. 程序调用 prepare()。 无论使用了哪种 HTTP 方法,prep

    16、are 都会被 调用到,因此 这个 方法 通常会被定义在一个 基 类中,然后在子类中 重 用。 prepare 可以产生输出 信息。 如果它调用了 finish (或 send_error 等函数),那么整个 处 理流程 就此结束。 4. 程序调用某个 HTTP 方 法: 例如 get()、 post() 、 put() 等。 如果 URL 的正则表达式模式中 有 分组匹配,那么相关 匹 配会作为参数传入方 法 。 下面是一个示范 initialize() 方法的例子: class ProfileHandler(RequestHandler): def initialize(self, dat

    17、abase): self.database = database def get(self, username): . app = Application( (r/user/(.*), ProfileHandler, dict(database=database), ) 其它设计用来被复写 的 方法有: get_error_html(self, status_code, exception=None, *kwargs) - 以字符串的形式 返回 HTML ,以供错误页面 使用。 get_current_user(self) - 查看下面的 用户认证一节 get_user_locale(self

    18、) - 返回 locale 对象, 以供当前用户使用。 get_login_url(self) - 返回登录网址,以 供 authenticated 装饰器 使用(默认位置 在 Application 设置中) get_template_path(self) - 返回模板文件的 路径(默认 是 Application 中的设置) 重 定向(redirect) Tornado 中的重定向有 两种主要方法:self.redirect,或者使 用 RedirectHandler。 你可以在使用 RequestHandler (例如 get)的 方法中使用 self.redirect,将用 户 重定向

    19、到别的地 方。 另外还有一个可选参 数 permanent, 你可以用它指定这次操 作为永久性重定向。 该参数会激发一个 301 Moved Permanently HTTP 状态, 这在某些 情况下 是有用的, 例如, 你要将页 面的原始 链接重定向时, 这种方式 会更有利于搜索引擎 优 化 (SEO)。 permanent 的默认值是 False,这是为了适用于 常见的操作,例如用 户 端在成功发 送 POST 请求 以后的 重定向。 self.redirect(/some-canonical-page, permanent=True) RedirectHandler 会在你初始化 App

    20、lication 时自动生成。 例如本站的下载 URL , 由较短的 URL 重 定向 到较长的 URL 的 方式 是这样的: application = tornado.wsgi.WSGIApplication( (r“/(a-z*)“, ContentHandler), (r“/static/tornado-0.2.tar.gz“, tornado.web.RedirectHandler, dict(url=“http:/ tornado-0.2.tar.gz“), , *settings) RedirectHandler 的默认状态码是 301 Moved Permanently, 不过

    21、如果 你想使用 302 Found 状态码,你需要 将permanent 设置为 False。 application = tornado.wsgi.WSGIApplication( (r“/foo“, tornado.web.RedirectHandler, “url“:“/bar“, “permanent“:False), , *settings) 注意,在 self.redirect 和 RedirectHandler 中,permanent 的默认 值是不同的。 这样做是有一定道理 的 ,self.redirect 通常会被用在自定义方法 中 ,是由逻辑事 件触发 的(例如环 境变 更

    22、、用户认证、以及 表 单提交)。而 RedirectHandler 是 在每次匹配到请求 URL 时被触发。 模板 你可以在 Tornado 中 使用任何一种 Python 支持的模板语言。但 是 相较于其它模 板而言, Tornado 自 带的模板系统速度更 快 ,并且也更灵活。具 体 可以查 看 template 模块的源码 。 Tornado 模板其实就是 HTML 文件 (也可以 是任何文本格式的文 件 ) , 其中包含 了 Python 控制结构和 表达式, 这些 控制结构 和表达式需要放在规 定 的格式标记符 (markup) 中: title % for item in item

    23、s % escape(item) % end % 如果你把上面的代码 命 名为 “template.html“ , 保存在 Python 代码的 同一目录中, 你就可以 这样来渲 染它 : class MainHandler(tornado.web.RequestHandler): def get(self): items = “Item 1“, “Item 2“, “Item 3“ self.render(“template.html“, title=“My title“, items=items) Tornado 的模板支持“ 控制语句” 和“ 表达语句” ,控制语句是使用 % 和 % 包

    24、起来的 例如 % if len(items) 2 %。表达语句是使 用 和 包起来的, 例 如 items0 。 控制语句和对应的 Python 语句的格 式基本完全 相同。我们支持 if、for 、 while 和 try,这些语句 逻辑结束的位置需要 用 % end % 做标记。我 们还通 过 extends 和 block 语句实现了模板继承。 这 些在 template 模块 的代码文档中有 着详细的描述。 表达语句可以是包括 函 数调用在内的任何 Python 表述。 模板中的相关 代码, 会在 一个单独 的名字空 间中 被执行, 这个名 字空间 包括了以下的一些对 象 和方法。 (

    25、注 意,下面列表中 的 对象 或方法在使用 RequestHandler.render 或者 render_string 时才存在的 ,如果你在 RequestHandler 外面直接使 用 template 模块,则它 们中的大部分是不存 在 的)。 escape: tornado.escape.xhtml_escape 的別名 xhtml_escape: tornado.escape.xhtml_escape 的別名 url_escape: tornado.escape.url_escape 的別名 json_encode: tornado.escape.json_encode 的別名 s

    26、queeze: tornado.escape.squeeze 的別名 linkify: tornado.escape.linkify 的別名 datetime: Python 的 datetime 模组 handler: 当前的 RequestHandler 对象 request: handler.request 的別名 current_user: handler.current_user 的別名 locale: handler.locale 的別名 _: handler.locale.translate 的別名 static_url: for handler.static_url 的別名 x

    27、srf_form_html: handler.xsrf_form_html 的別名 reverse_url: Application.reverse_url 的別名 Application 设置中 ui_methods 和 ui_modules 下面的所有项目 任何传递给 render 或者 render_string 的关键字参数 当你制作一个实际应 用 时, 你会需要用到 Tornado 模板的所有功能, 尤其是 模板 继承功能。所有这些 功 能都可以在template 模块 的代码文档中了解到 。(其中一 些功能是在 web 模块中 实现的,例如 UIModules) 从实现方式来讲 ,

    28、 Tornado 的模板会被直接 转成 Python 代码。 模 板中 的语句会逐 字复制到一个 代表 模板 的函数中去。我们不 会 对模板有任何限制,Tornado 模板 模块的设计宗旨就是 要 比 其他模板系统更 灵活 而且限制更少。 所以, 当 你的模板语 句里发生了随机的错 误 ,在执行模板时 你 就会 看到随机的 Python 错 误信息。 所有的模板输出都已 经 通过 tornado.escape.xhtml_escape 自动转义(escape),这 种默认行为, 可以 通过 以下几种方式修改: 将 autoescape=None 传递 给 Application 或者 Temp

    29、lateLoader、 在模 板文件中加入 % autoescape None %、或者在简单表 达语句 . 写成 % raw .%。另外你 可以在上述 位置将 autoescape 设为一个自定义函数, 而 不仅仅是 None。 Cookie 和安全 Cookie 你可以使用 set_cookie 方法在用户的浏览中设 置 cookie : class MainHandler(tornado.web.RequestHandler): def get(self): if not self.get_cookie(“mycookie“): self.set_cookie(“mycookie“, “

    30、myvalue“) self.write(“Your cookie was not set yet!“) else: self.write(“Your cookie was set!“) Cookie 很容易被恶意 的 客户端伪造。加入你 想 在 cookie 中保存当 前 登陆用户的 id 之类的信息,你需要 对 cookie 作签名以 防 止伪造。Tornado 通 过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种 功 能。 要使用 这些方法, 你需要 在创 建应用时提供一个密 钥 , 名字为 cookie_secret 。 你可以把 它作

    31、为一个关键词参 数 传入应用的设置中: application = tornado.web.Application( (r“/“, MainHandler), , cookie_secret=“61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o /Vo=“) 签名过的 cookie 中包 含了编码过的 cookie 值,另外还有一个时 间 戳和一 个 HMAC 签名。如果 cookie 已经过期或者 签 名不匹配,get_secure_cookie 将 返回 None,这和没有设 置 cookie 时的 返回 值 是一样的。上面例子 的 安全 cookie 版本如

    32、下: class MainHandler(tornado.web.RequestHandler): def get(self): if not self.get_secure_cookie(“mycookie“): self.set_secure_cookie(“mycookie“, “myvalue“) self.write(“Your cookie was not set yet!“) else: self.write(“Your cookie was set!“) 用户认 证 当前已经认证的用户 信 息被保存在每一个请 求 处理器的 self.current_user 当中, 同时在模板

    33、的 current_user 中也是。默认情况 下,current_user 为 None。 要在应用程序实现用 户 认证的功能,你需要 复 写请求处理 中 get_current_user() 这 个方法,在其中判 定当前用户的状态,比如通过 cookie 。 下面的例子 让 用户简单地使用一个 nickname 登陆应用, 该 登陆信息将被 保存到 cookie 中: class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): return self.get_secure_cookie(“user“)

    34、 class MainHandler(BaseHandler): def get(self): if not self.current_user: self.redirect(“/login“) return name = tornado.escape.xhtml_escape(self.current_user) self.write(“Hello, “ + name) class LoginHandler(BaseHandler): def get(self): self.write( Name: ) def post(self): self.set_secure_cookie(“user

    35、“, self.get_argument(“name“) self.redirect(“/“) application = tornado.web.Application( (r“/“, MainHandler), (r“/login“, LoginHandler), , cookie_secret=“61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o /Vo=“) 对于那些必须要求用 户 登陆的操作,可以使 用 装饰 器 tornado.web.authenticated。 如果一个方 法套上了这个装饰器 , 但是当前用 户并没有登陆的话, 页 面会被重定向到

    36、login_url(应用配置中的一个 选项),上 面的例子可以被改写 成 : class MainHandler(BaseHandler): tornado.web.authenticated def get(self): name = tornado.escape.xhtml_escape(self.current_user) self.write(“Hello, “ + name) settings = “cookie_secret“: “61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=“, “login_url“: “/login“, applic

    37、ation = tornado.web.Application( (r“/“, MainHandler), (r“/login“, LoginHandler), , *settings) 如果你使用 authenticated 装饰器来装饰 post() 方法,那么在用户没 有登陆的状 态下, 服务器会返 回 403 错误。 Tornado 内部集成了对 第三方认证形式的支 持 ,比如 Google 的 OAuth 。参 阅 auth 模块 的代码文 档以了解更多信息。 for more details. Checkauth 模块以了 解更多的细节。在 Tornado 的源码中有一个 Blog

    38、 的例子,你 也可以从 那里看到 用户认证的方法(以 及 如何在 MySQL 数据库 中保存用户数据)。 跨 站伪 造请 求的 防范 跨站伪造请求(Cross-site request forgery) , 简 称为 XSRF ,是个 性化 Web 应用 中常见的一个安全问 题 。前面的链接也详细 讲 述了 XSRF 攻击的 实现 方式。 当前防范 XSRF 的 一种 通用的方法,是对每 一 个用户都记录一个无法预知的 cookie 数据, 然后要求 所有提交的请求中都 必 须带有这个 cookie 数 据。 如果此数 据不匹配 ,那么这 个请 求就可能是被伪造的 。 Tornado 有内建的

    39、 XSRF 的防范机制, 要使 用此机制,你需要在 应 用配置中加 上 xsrf_cookies 设定: settings = “cookie_secret“: “61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=“, “login_url“: “/login“, “xsrf_cookies“: True, application = tornado.web.Application( (r“/“, MainHandler), (r“/login“, LoginHandler), , *settings) 如果设置了 xsrf_cookies,那么 Torn

    40、ado 的 Web 应用将对所 有用户 设置一 个 _xsrf 的 cookie 值 ,如果 POST PUTDELET 请求中没有这 个 cookie 值, 那么这 个请求会被直接拒绝 。 如果你开启了这个机 制 , 那么在所有 被提交的 表单中, 你都 需要加上一个域来提 供 这个值。你可以通过 在 模板中使用 专门的 函 数 xsrf_form_html() 来做到这一点: xsrf_form_html() 如果你提交的是 AJAX 的 POST 请求,你还是需 要在每一个请求中通 过 脚本添加 上 _xsrf 这个值。下面 是在 FriendFeed 中的 AJAX 的 POST 请求

    41、,使用 了 jQuery 函数来为所有请求组东添加 _xsrf 值: function getCookie(name) var r = document.cookie.match(“b“ + name + “=(;*)b“); return r ? r1 : undefined; jQuery.postJSON = function(url, args, callback) args._xsrf = getCookie(“_xsrf“); $.ajax(url: url, data: $.param(args), dataType: “text“, type: “POST“, success:

    42、 function(response) callback(eval(“(“ + response + “)“); ); ; 对于 PUT 和 DELETE 请求 (以及不使用将 form 内容作为参数的 POST 请求) 来说, 你也可以在 HTTP 头中 以 X-XSRFToken 这个参数传递 XSRF token 。 如果你需要针对每一 个 请求处理器定制 XSRF 行为,你可以重 写 RequestHandler.check_xsrf_cookie()。例如你需要使用一个不 支 持 cookie 的 API , 你可以通 过将 check_xsrf_cookie() 函数设空来禁用 X

    43、SRF 保护机制。 然而如果 你需要同 时支 持 cookie 和非 cookie 认证方式, 那么 只要当 前请求是通 过 cookie 进行认证 的 ,你就应该对其使用 XSRF 保护机制, 这一点 至关重要。 静态文 件和 主动 式文 件缓 存 你能通过在应用配置 中 指定 static_path 选项来提供静态文件服务 : settings = “static_path“: os.path.join(os.path.dirname(_file_), “static“), “cookie_secret“: “61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o

    44、/Vo=“, “login_url“: “/login“, “xsrf_cookies“: True, application = tornado.web.Application( (r“/“, MainHandler), (r“/login“, LoginHandler), (r“/(apple-touch-icon.png)“, tornado.web.StaticFileHandler, dict(path=settingsstatic_path), , *settings) 这样配置后, 所有 以 /static/ 开头的请求, 都 会直接访问到指定的 静 态文件目录, 比如http:

    45、/localhost:8888/static/foo.png 会从指定的静态文件目录 中 访问 到 foo.png 这个文件。 同时 /robots.txt 和/favicon.ico 也是会自动 作为静态文 件处理(即使它们不 是 以 /static/ 开头)。 在上述配置中, 我们使用 StaticFileHandler 特别指定了让 Tornado 从根目录伺 服 apple-touch-icon.png 这个文件,尽管它的 物理位置还是在静态 文 件目录中。 (正则表达式 的匹 配分 组的目的是向 StaticFileHandler 指定所请求 的文件名 称, 抓取到的分 组会以 方法

    46、参数的形式传递 给 处理器。 ) 通 过相同的 方式, 你也可 以从站点的更目录伺 服sitemap.xml 文件。 当然, 你也可以通过在 HTML 中使用 正确的 标签来 避免这样的根目录 文件 伪造行为。 为了提高性能,在浏 览 器主动缓存静态文件 是 个不错的主意。这样 浏 览器就不需要 发送 不必要的 If-Modified-Since 和 Etag 请求,从而影响页面的 渲 染速度。 Tornado 可以通过内建 的“ 静态内容分版(static content versioning)” 来直接支持这 种功能。 要使用这个功能,在 模 板中就不要直接使用 静 态文件的 URL 地

    47、址了 ,你需要在 HTML 中使用 static_url() 这个方法来提供 URL 地址: FriendFeed - _(“Home“) static_url() 函数会将相对地址转成一个类 似 于 /static/images/logo.png?v=aae54 的 URI ,v 参数是 logo.png 文 件的散列 值, Tornado 服务器 会把它发给浏览器, 并 以此为依据让浏览器 对 相关内容做永 久缓存。 由于 v 的值是基于文件 的内容计算出来的, 如果 你更新了文件, 或者重启 了服务器 , 那么就会得到一个新 的 v 值, 这样浏览器就会请 求服务器以获取新的 文 件内容

    48、。 如 果文件的内容没有改 变 ,浏览器就会一直使 用 本地缓存的文件,这 样 可以显著提高 页 面的渲染速度。 在生产环境下,你可 能 会使用nginx 这样的更有 利于静态文件 伺服 的服 务器,你可 以将 Tornado 的文件 缓存指定到任何静态 文 件服务器上面,下面 是 FriendFeed 使用的 nginx 的相 关配 置: location /static/ root /var/friendfeed/static; if ($query_string) expires max; 本 地化 不管有没有登陆,当 前 用户的 locale 设置可以 通过两种方式访问到 : 请求处理器 的 self.locale 对象、 以及模板中的locale 值。 Locale 的名称 (如 en_US)可以 通 过 locale.name 这个变量访问到, 你可以使 用 locale.translate 来进行本地化 翻 译。 在模板中, 有一个 全局方法叫 _(), 它的 作用就是进行本地化 的 翻译。 这个 翻 译方法有两种使用形 式 : _(“Translate this string“) 它会基于当前 locale 设 置直接进行翻译,还 有 一种是: _(“A person liked this“, “%(num)d people liked

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:tornado中文教程.pdf
    链接地址:https://www.docduoduo.com/p-6299221.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开