6

I am using the Backbone.js router to fire certain initialization methods when the user hits certain URL routes. So going to /posts/1 via a vanilla anchor tag should fire whatever callback is associated with /posts/:id in my Backbone router. This works fine in modern browsers when Backbone.history.start({ pushState : true }) is set. However, in IE, users who try to hit /posts/1 will be redirected to /#posts/1, which is just my home page with a meaningless hash string.

To be clear, I do not need pushState. I am not trying to push URLs to the browser history. I am just trying to read them, then fire a callback, which should be feasible in any browser.

Seems like simple functionality but I am stumped.

Thanks!

Squirkle
  • 933
  • 1
  • 7
  • 22
  • Do you need your server to respond to the URL /posts/1, and is that considered a different page for your app? Could you just pull down the post information in an XHR and display it on the page? – MrGrigg Dec 06 '12 at 18:06
  • I think you need to post some code -- it's a bit hard to tell what you mean. The redirect to the URL fragment is normal fallback behavior for browsers that don't support push-state. Are you saying the route isn't getting hit correctly in those cases? – McGarnagle Dec 07 '12 at 03:33

3 Answers3

7

I can answer my own question here. The type of functionality I needed here could be achieved the following way:

var suffix_pattern = new RegExp('\/?' + config.history_root + '\/?','i');

// if IE
if (!Modernizr.history) {

    // initialize router/Backbone.history, but turn off route parsing,
    // since non-window.history parsing will look for a hash, and not finding one,
    // will break our shit.
    Backbone.history.start({ silent: true, hashChange: true });

    // convert any post-# elements to a standard URL to be parsed by our router
    var subroute = window.location.hash.replace('#', '/').split('?')[0],
           route = window.location.pathname.replace(suffix_pattern, '') + subroute;

    Backbone.history.loadUrl(route);
} else {
    Backbone.history.start({ pushState: true, silent: true });
    Backbone.history.loadUrl(Backbone.history.getFragment().replace(suffix_pattern, '').split('?')[0]);
}
Squirkle
  • 933
  • 1
  • 7
  • 22
0

this worked for me: Backbone.history.start({root: '/my_app_dir_here/'});

born2net
  • 24,129
  • 22
  • 65
  • 104
0

If you don't care about ajax page loads in browsers that don't support pushState, use option {hashChange: false}. This will cause hard page loads every time a route changes.

e.g.

Backbone.history.start({ pushState: true, hashChange:false });

From the Backbone.js docs:

If you'd like to use pushState, but have browsers that don't support it natively use full page refreshes instead, you can add {hashChange: false} to the options.

nappels
  • 1
  • 2
  • 1
    Note that the accepted answer above applies to an issue in a Backbone version that is now over two years old. The problem above no longer exists. – Squirkle Jun 12 '15 at 16:14