Reloading the page or manually type URL like "localhost/mysite.com/contact" gives wrong "Not Found"(404 error) on the server. This is because MVC does not know about angular routing and by MVC pattern it will look for an MVC page for 'contact' which does not exist in MVC routing path. I think there is a solution by .haccess file by redirect all links to the index page, but it, not a good idea.
I already add a baseURL constant to the application in head.
and the js part is below:
app.config(function($routeProvider,$locationProvider) {
$routeProvider.
when("/contact", {
templateUrl : "partial/contact.html"
}).
when("/aboutus", {
templateUrl : "aboutus.html"
}).
when("/service", {
templateUrl : "service.html"
}).
otherwise({
redrictTo: "index.html"
})
$locationProvider.html5Mode(true);
});
How can I fix the issue angular to get the correct page (localhost/mysite.com/contact) when I go to the contact page by typing URL manually.
Angular routing, in HTML 5 mode, uses the history API under the hood.
The history API is designed with the intention that you:
- Load a page
- Run JavaScript to change the content of the page in such a way that it becomes a different page
- Use
pushState
to change the URL in the browser so it is the URL of that page
The idea being that using JavaScript for step 2 should be faster (or better in some other way) than loading the whole page from the server.
This is because MVC does not know about angular routing and by MVC pattern it will look for an MVC page for 'contact' which does not exist in MVC routing path
This is your problem. The history API is designed so that your server side code should know about that.
If a user went directly to the second URL, then the server should be able to present them with that page directly. i.e. it shouldn't throw a 404 and it shouldn't load the homepage and then transform it with JavaScript.
JavaScript is unreliable. Follow the principles of Progressive Enhancement and Unobtrusive JavaScript
tl;dr: You need to write server side code to mirror your client side code.
If you don't want to use URLs that the server can recognise for each page, then don't use $locationProvider.html5Mode(true);
and go back to the bad old days of hashbangs.
Quentin's solution of doing the rendering server-side is absolutely correct, if you can afford to get server-side rendering to work. If you can't get it to work, or it turns out to be too costly to get it working, then you can go with a couple solutions.
Disable HTML 5 mode URL handling
// Remove/change this line - $locationProvider.html5Mode(true);
Quentin has already suggested this solution. He warns strongly against it, and there are some drawbacks. However, it still might be the correct trade off for you. See below.
Use server-side redirects so your URL routing is only handled on the client side
You mentioned this in your question:
I think there is a solution by .haccess file by redirect all links to the index page ...
Most production routers are capable of doing this type of routing. This doesn't preclude you from routing other apps on the same server, if you are careful to keep the URLs for each app from clobbering each other.
Generally you should prefer the other solution of turning off HTML 5 routes, and going with fragment identifier URLs for the client. However it could make sense to use this option when you're doing brownfield development and have to mimic an existing URL structure by using HTML 5 mode URLs.
Trading off cost vs effort
You said you heard it was "not a good idea" to hack the .htaccess
to always return the client code. Generally speaking, this is correct. This will rely on the client-side MVC framework to do routing, and will partially waste the ability of the server to do routing. Fully leveraging HTTP caching will also probably require additional work with this approach, and won't ever be quite perfect.
As Quentin pointed out, there are also robustness trade-offs you are making if you go with this solution. JavaScript breaks if you are not very careful, and can leave your app broken. Some people choose to disable JavaScript. Some sites also aren't capable of scraping a web page that is only rendered on the client side.
The issues of having no JavaScript on the client are decreasing in frequency over time, but you may find that having a less robust site may be a painful thorn for your user base and cause you a significant loss in users. If so, you may be justified in cost to get server-side routing to work reliably and do progressive enhancement.
If you don't have a lot of users with JavaScript disabled, then it might be worth it to you to hack the solution (html5Mode == false
or .htaccess
hacks), and focus on other things like building out features that will make you more revenue or retain users on your site for longer.