krakig krakig - 3 months ago 39
AngularJS Question

Configuring .htaccess file to serve angular and api routes

I am lost with the configuration of my .htaccess file. I have a website serving the client part (angular.js app) and api routes, which are handled with the slim framework.

My html pages are served with the ui-router, but in order to handle the page refresh, I have to do an url rewrite.

That's my file so far :

DirectoryIndex index.html index.php

#
# Redirect all to index.php
#
RewriteEngine On

# if a directory or a file exists, use it directly (static assets)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

#if route starts with "api", route to index.php (slim framework)
RewriteRule ^api/ index.php [L]
#else (it means we are serving the angular routes)
RewriteRule ^(.*) /index.html [NC,L]


It's, of course, not working. The real problem is that I don't know if my logic is good at first (or I am far far far far away...), and then how to write it (I am new to apache syntax and I don't really understand everything).

Answer

With 2 virtual hosts

API htaccess:

RewriteEngine On

# Redirect Trailing Slashes
RewriteRule ^(.*)/$ /$1 [L]

# Redirect Root
RewriteRule ^$ api.php [L]

# Handle API Requests
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ api.php [L]

Front virtual host:

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 (html5mode)
RewriteRule ^ /index.html

# Redirect /api to API virtual host
<Location /api>
  ProxyPass http://127.0.0.1:8090 # Change here to the API virtual host binding
</Location>

The front virtual host will serve the requested file if it exists (except for /api/*), or will serve index.html if it does not. All /api requests will be forwarded to API virtual host. The API virtual host will serve any existing file, or will rewrite to api.php, which will handle your API calls.

With 1 virtual host

<IfModule mod_negotiation.c>
  Options -MultiViews
</IfModule>

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]


RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^ api.php [L]

# If the requested resource doesn't exist, use index.html (html5mode)
RewriteRule ^ /index.html [L]

Same behavior as above

WARNING: trying to include a non-existant file into the angular app may produce an infinite loading loop (index.html will load, then it will load the non-existant file, which will be index.html due to html5mode, etc...)