Search code examples
ember.jstornado

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


Note: I am new to Tornado.

To recreate my problem I have the following Python file:

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()

I then have an Ember project that has two routes (/route1 and /route2) with one button on each which just transitions to the other route, and an application route that transitions to route1 in beforeModel. I copy the dist directory generated by Ember to the directory which contains the Python file above. When I run the Python file and navigate to localhost:34567 this automatically transitions to localhost:34567/route1, I can then press the buttons to navigate between pages fine. However, when I refresh the page or enter localhost:34567/route1 in the address bar I get a "404: Not Found" page. What am I missing from my Tornado setup?

Thanks


Solution

  • Ember (as the most of its competitors) has its own client-based router, that uses pushState (or/and hash routes). Ember, unless you do, does not make any request to the backend.

    The solution is simple, in Tornado use the IndexHandler for all paths you expect. The common way is to handle all paths, but assets. Example:

    # 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),
    ])