I'm using html5Mode=true with AngularJS routing. Works fine. When I access the site with IE, Angular routing falls back to Hashbang URI's like http://example.com/#!/route-name. That's all fine. Except in Express I need to know the route, because it tells me which html file to serve from Express. The # part of the url is not sent to the server.
My question is, how can I let my server know which AngularJS route is being requested with hashbang routing in IE? I was thinking of configuring Angular somehow to send the route as an http header that I can read in express, but I don't know how to do that. Any ideas?
Update: Based on feedback I got, let me tell you that the site has templates. One for the homepage and one for all the other pages. They are both pretty different. Based on the route, the server needs to know when to serve the file for the homepage and when to serve the file for the other pages.
There seems no client-side answer as per the answer of Sergiu Paraschiv. So I have investigated a server-side solution that requires only one thing on the client. Make sure you always links as you would do in html5Mode which is linking to /xxxxx and not /#!/xxxxx.
Then In html5Mode and IE9 and lower what happens is that AngularJS redirects everything /xxxxx to /#!/xxxxx. In Express this makes the url / and the referer /xxxxx. This is something that you can check for quite easily.
If you want to cater for IE8 and lower to, it's unfortunate that Angular uses window.location.href in this fall back scenario redirecting to /#!/xxxxx. See github / angular.js / src / ng / browser.js line 169. Using window.location.href causes IE8 and lower to not send the referer.
Here's a server-side (Express 3.x) solution that resolves the Angular hashbang route from the referer value or a previousUrl session variable for IE8 and lower.
app.use(function(req, res, next) {
if (req.url.match(/\/api/))
return next(); // /api/something should proceed to next in middleware
console.log(req.url, req.headers)
//IE does not support html5Mode so /xxxxx is redirected to /#!/xxxxx
//effectively making the url / and the referer /xxxxx
//I check for that here and if xxxxx is not home I present page.html
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-8]{1}[.0-9]*)/) &&
req.url.match(/^\/[\w-]+$/)
) {
//However IE8 does not report the referer when doing a redirect using window.locarion.href
//so I store the initially requested url /xxxxx in session...
req.session.previousUrl = req.url;
//console.log('IE8 saving the url here', req.session.previousUrl);
}
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-8]{1}[.0-9]*)/) &&
!req.headers['referer'] &&
req.url === '/' &&
req.session.previousUrl &&
req.session.previousUrl !== '/home'
) {
//continuation on the IE* referer story (aka the next redirected request)...
//... and checked for the url stored in session here ;)
return res.sendfile('public\\page.html');
}
if (req.headers['user-agent'] &&
req.headers['user-agent'].match(/MSIE ([7-9]{1}[.0-9]*)/) &&
req.url === '/' &&
req.headers['referer'] &&
req.headers['referer'].match(/^https?:\/\/(?:www)?\.example\.com\/(?!home$)([\w-]+)$/)
) {
return res.sendfile('public\\page.html');
}
if (req.url.match(/\/home|\/$/))
return res.sendfile('public\\home.html'); //for the home pages we're going to use home.html
res.sendfile('public\\page.html'); //for everything else we're going to use page.html
});
I'm sure that there are scenario's where this fails, but it worked for me in my tests and if it fails, that will only fail for IE9- browsers (as per the regexp's).