sublime
sublime

Reputation: 4161

Getting backbone routing to work with pushstate and node.js/express as server

I'm trying to build a single page app with backbone.js on front end and node.js/express as server, I want to have a base HTML file for the root, and then when user navigates to any path such as

mydomain.com/foo/bar

I want to be able to handle that path on the client side by javascript instead of making a round trip to server. I am reading about backbone routing and HTML5 push state. In this article he describes push state like this,

In fact, PushState is really nothing more than a standard API for JavaScript, that allows us to manipulate the browser history by “push”ing full URLs into the browser’s URL without making a round trip to the server, and respond to changes in the URL with Javascript – all without the use of URL hash fragments.

but when I use push state it does actually makes a server request and expects server to deliver contents under /foo/bar . I don't understand how I can avoid that.

Now let's assume that even with push state, your client is going to make a server request under mydomain.com/foo/bar when you visit this URL directly. In that case, since I'm serving the default HTML file, and this default HTML file has links to scripts in it:

<script type="text/javascript" src="/scripts/myscript.js" ></script>

When this HTML loads, it starts looking for scripts under /foo directory instead of root since the server was requested under /foo which obviously does not exist. How do I fix this?

I'm really confused at this point. I'd like to know how URL routing is usually done in a single page application. Any help will be greatly appreciated. You can also refer to this other question I have posted about the same issue: Backbone Router : Get rid of # in the URL

Upvotes: 4

Views: 1336

Answers (1)

Esteban
Esteban

Reputation: 2579

The solution you're trying to implement is very interesting but not that simple. When your server gets a request to mydomain.com/foo/bar, you should redirect to your root with some parameter that the frontend (JavaScript) app can pick-up to know what the original request was for. For example:

  1. Client sends GET http://mydomain.com/foo/bar
  2. Server redirects (responds 302 with Location header set) to http://mydomain.com/#!/foo/bar
  3. Your SPA is loaded in the browser, and on startup you check for the hash and find #!/foo/bar, so you remove the hash and trigger the /foo/bar route (that's a push-state). Your resulting URL is again http://mydomain.com/foo/bar: the original URL the user browsed to.

Grooveshark does something similar to this, though it actually responds with a page to the request sent in 1., which does the hash replacement in the client and then sends another request to the server. It looks unnecessary to me, maybe I'm overlooking something.

Upvotes: 4

Related Questions