🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 静态文件和主动式文件缓存 你能通过在应用配置中指定 `static_path` 选项来提供静态文件服务: ``` settings = { "static_path": os.path.join(os.path.dirname(__file__), "static"), "cookie_secret": "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/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=settings['static_path'])), ], **settings) ``` 这样配置后,所有以 `/static/` 开头的请求,都会直接访问到指定的静态文件目录, 比如 http://localhost:8888/static/foo.png 会从指定的静态文件目录中访问到 `foo.png` 这个文件。同时 `/robots.txt` 和 `/favicon.ico` 也是会自动作为静态文件处理(即使它们不是以 `/static/` 开头)。 在上述配置中,我们使用 `StaticFileHandler` 特别指定了让 Tornado 从根目录伺服 `apple-touch-icon.png` 这个文件,尽管它的物理位置还是在静态文件目录中。(正则表达式 的匹配分组的目的是向 `StaticFileHandler` 指定所请求的文件名称,抓取到的分组会以 方法参数的形式传递给处理器。)通过相同的方式,你也可以从站点的更目录伺服 `sitemap.xml` 文件。当然,你也可以通过在 HTML 中使用正确的 `&lt;link /&gt;` 标签来避免这样的根目录 文件伪造行为。 为了提高性能,在浏览器主动缓存静态文件是个不错的主意。这样浏览器就不需要发送 不必要的 `If-Modified-Since` 和 `Etag` 请求,从而影响页面的渲染速度。 Tornado 可以通过内建的“静态内容分版(static content versioning)”来直接支持这种功能。 要使用这个功能,在模板中就不要直接使用静态文件的 URL 地址了,你需要在 HTML 中使用 `static_url()` 这个方法来提供 URL 地址: ``` <html> <head> <title>FriendFeed - {{ _("Home") }}</title> </head> <body> <div><img src="{{ static_url("images/logo.png") }}"/></div> </body> </html> ``` `static_url()` 函数会将相对地址转成一个类似于 `/static/images/logo.png?v=aae54` 的 URI,`v` 参数是 `logo.png` 文件的散列值, Tornado 服务器会把它发给浏览器,并以此为依据让浏览器对相关内容做永久缓存。 由于 `v` 的值是基于文件的内容计算出来的,如果你更新了文件,或者重启了服务器 ,那么就会得到一个新的 `v` 值,这样浏览器就会请求服务器以获取新的文件内容。 如果文件的内容没有改变,浏览器就会一直使用本地缓存的文件,这样可以显著提高页 面的渲染速度。 在生产环境下,你可能会使用[nginx](http://nginx.net/)这样的更有利于静态文件 伺服的服务器,你可以将 Tornado 的文件缓存指定到任何静态文件服务器上面,下面 是 FriendFeed 使用的 nginx 的相关配置: ``` location /static/ { root /var/friendfeed/static; if ($query_string) { expires max; } } ```