当 运行 使用 Tornado 且内容使用 Ember 生成的 HTTP 服务器无法刷新页面时

When running a HTTP server using Tornado with content generated using Ember cannot refresh page

注意:我是 Tornado 新手。

为了重现我的问题,我有以下 Python 文件:

import tornado.httpserver
import tornado.ioloop
import tornado.web

class IndexHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        self.render("dist/index.html")

def start_server():
    app = tornado.web.Application([
        (r'/', IndexHandler),
        (r'/assets/(.*)', tornado.web.StaticFileHandler, {"path": "dist/assets"}),
    ])

    ioLoopInstance = tornado.ioloop.IOLoop.instance()

    http_server = tornado.httpserver.HTTPServer(app, io_loop=ioLoopInstance)
    http_server.listen(34567)
    ioLoopInstance.start()

if __name__ == '__main__':
    start_server()

然后我有一个 Ember 项目,它有两条路线(/route1 和 /route2),每条路线上有一个按钮,只是过渡到另一条路线,还有一个应用程序路线,过渡到 beforeModel 中的 route1。我将 Ember 生成的 dist 目录复制到上面包含 Python 文件的目录。当我 运行 Python 文件并导航到 localhost:34567 时,它会自动转换到 localhost:34567/route1,然后我可以按按钮在页面之间导航。但是,当我刷新页面或在地址栏中输入 localhost:34567/route1 时,我得到一个“404:未找到”页面。我的 Tornado 设置中缺少什么?

谢谢

Ember(作为其大多数竞争对手)有自己的基于客户端的路由器,使用pushState(or/and哈希路线)。 Ember,除非你这样做,否则不会向后端发出任何请求。

解决方案很简单,在 Tornado 中对您期望的所有路径使用 IndexHandler。常见的方法是处理所有路径,但不包括资产。示例:

# note 1: '.*' match all
# note 2: Tornado router matches paths in the order,
#         so match all should be the last
app = tornado.web.Application([
    (r'/assets/(.*)', tornado.web.StaticFileHandler, {"path": "dist/assets"}),
    (r'/.*', IndexHandler),
])