Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular ui-router pressing refresh causes 404 error

OK, I know this is an open ended question, but -

I'm running an application using AngularJS 1.4.x and ui-router. For the most part everything works fine and as expected. My various pages use ui-sref's to navigate, pages show up as expected, and the URL that's showing looks correct. However, if I refresh the page (F5) on any page at all, it causes a 404 error to occur. And typing in the URL no longer works.

Things that might be involved:

  • I turned on the $locationProvider.html5Mode(true) flag
  • I use

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams)

    to manage page access (authentication)

  • <base href="/"> is in my index.html because html5Mode() won't work without it
like image 485
Todd Davis Avatar asked Jan 08 '23 20:01

Todd Davis


1 Answers

Q: When you refresh the page, what is actually happening?

A: You're sending an HTTP request via your browser to a server. GET /whatever. So the server will need to have a route set up for this request that responds with index.html. Currently, you're getting a 404 because your server doesn't have a route that matches the request to GET /whatever.

Q: Why?

A: When you make a request via your browser (rather than through AJAX), your browser will try to display the response to you. Ex. if the response is JSON, it'll show you JSON. If it's a string, it'll show you a string. If it's an html page, it'll show you that. You can't just send back a template for whatever route, because if you do, it'll just render that template with no other context. You need index.html to load angular, run your controller, place the template in it's ui-view container, etc.

(What'll happen is index.html will be sent back, UI Router will check the route, make a request for the templateUrl, run the controller, and then render it.)

Q: How?

A: That depends on a) what type of server you're using and b) your file structure. You'll probably want some sort of catch all route at the end of your route file that serves index.html. This is how I do it with Node/Express:

app.get('/*', function(req, res) {
  var url = path.resolve(__dirname + '/../client/index.html');
  res.sendFile(url, null, function(err) {
    if (err) res.status(500).send(err);
    else res.status(200).end();
  });
});
like image 166
Adam Zerner Avatar answered Jan 23 '23 00:01

Adam Zerner