Reputation: 3789
I have a single page app with a router and html5mode enabled in
/account/
->index.html
The router looks like this:
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/account', {
templateUrl: 'account/views/welcome.html',
}) //works
.when('/account/emails', {
templateUrl: 'account/views/email.html',
controller: 'emailController'
}) //404 error
.when('/account/wallet', {
templateUrl: 'account/views/wallet.html',
}) //404 error
.when('/account/settings', {
templateUrl: 'account/views/settings.html',
controller: 'settingsController'
}) //404 error
.when('/account/logout', {
templateUrl: 'account/views/logout.html',
}) //404 error
});
Now I also have an .htaccess file in
/account/
->.htaccess
The htaccess looks like this:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
As expected, when I go to //localhost/account/index.html or //localhost/account/ the URL is handled properly. Clicking through the navigation works correctly as well. However if I try to refresh the page at any of the routed links, or try to access them directly from the address bar, I get the Apache2 Ubuntu Default Page.
Not sure what I am doing wrong here as this seems to be pretty straight forward?
Also, if I change RewriteRule ^ /index.html
to RewriteRule ^ /account/index.html
instead of getting the default Apache page, I get a 404:
Not Found
The requested URL /account/index.html was not found on this server.
Upvotes: 1
Views: 1135
Reputation: 3789
Turns out this solved the problem
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.html
</IfModule>
Upvotes: 0
Reputation: 2186
Looks like Apache is barfing on the # in the URL that angular uses for it's routes. You need something like this:
RewriteEngine on
# If an existing asset or directory is requested go to it as it is
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^(.*) /index.html [NC,L]
This is going to make it skip files and head to index.html when angular requests a file.
Upvotes: 1
Reputation: 963
I had a similar issue quite some time ago, and there are a few pieces to check.
In your index.html
file's <head>
, make sure that you have set the base href:
<head>
<base href="/">
...
</head>
Your .htaccess file looks essentially like what mine looked like when I wrote it. Here is what I used (the rewrite is probably sloppy, but it worked for me!):
# Enable URL rewriting/redirecting
RewriteEngine On
RewriteBase /
# if requested filename is not a file that exists
RewriteCond %{REQUEST_FILENAME} !-f
# AND if requested filename is not a directory that exists
RewriteCond %{REQUEST_FILENAME} !-d
# THEN rewrite the URL to be /#/PREVIOUS_URL
RewriteRule ^(.*)$ /#/$1 [L]
You already have the html5Mode
set to true, as seen in your code:
app.config(function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
...
});
Upvotes: 2