26

Obviously, there are a lot of mod rewrite discussions and answers all across the web. However, I am having a hard time grasping them. So I thought I would ask here.

I'm asking for rewrite rules to do what Andy Joslin explained in the comments here: https://stackoverflow.com/a/11100438

This is my current dir structure at the root of example.com

  • app/
  • app/index.html (the "root" of the angular js application)
  • api (This will be a symfony 2 app that is used for the 'api'. I'll be sending ajax requests to and from here from angular.)

I would like to redirect all requests to app/index.html except for requests to /api.

For example:

http://example.com/categories/electronics/ipod would actually be like going to http://example.com/app/index.html/categories/electronics/ipod

I would like for the app/index.html part to be hidden however.

Then, there would be an exception for requests to http://example.com/api because I will need to make ajax requests to those url paths.

Thanks for any and all help/guidance.

3
  • 7
    I don't think this question should be closed it's about angularjs and url-rewrite both topics are relevant. Commented Mar 13, 2013 at 22:28
  • This makes no sense that this is marked "off topic". It' is not off topic. Commented Mar 15, 2013 at 18:33
  • @casperOne, please open this back up. Commented Mar 15, 2013 at 18:34

5 Answers 5

32

The accepted answer to this question is outdated. You can now use the FallbackResource directive in your conf file with Apache 2.2.16+.

FallbackResource /app/index.html

If you want the FallbackResource directive to ignore the "/api" routes:

<Directory /api>
FallbackResource disabled
</Directory> 
Sign up to request clarification or add additional context in comments.

2 Comments

Cool directive. However, how can this be used while ignoring requests to "/api"? Which is what my original question was.
It can if you set it to specifically ignore the /api routes. I have edited the answer to reflect this.
17

Here's something to get you going (put this inside your /.htaccess file):

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !/api

# otherwise forward it to index.html 
RewriteRule ^.*$ - [NC,L]
RewriteRule ^app/. /app/index.html [NC,L]

NOTE: For newer Apache versions see also the next answer, which uses the much easier FallbackResource

3 Comments

Thanks, I'll use what I can from that. I'm working through a popular tutorial on rewrites now. I'm thinking though that what I want to do is not serve a file just because it exists. The problem with that is someone could request what angular calls a 'partial' file and it would serve it, etc. I'm going to redirect everything to app/index.html Then I'll explicitly skip certain directories such as css/ img/
This code almost solved my problem... I had to change the app rule a little bit, I left my working example on this answer: stackoverflow.com/a/15415902/54848
where to keep this file if using localhost:xxxx ?
0

The problem with this answer is that you still want 404s for file-not-found. Depending on how a person is building their front-end application, its very common for people to have css or other files return 404, especially if they are building larger dynamic applications, or are outsourcing the front-end work. Also, angular routes are usually not related to anything on the file system. The above may work if you narrow it down to a single directory. For instance, I will often use a common prefix for all angular routes that is not related to the file-system layout (/ajs/). If you can do

<Directory /ajs>
FallbackResource /app/index.html
</Directory> 

Then it would make more sense, but that doesn't seem to work for me. Using a common prefix also makes the backend rules much simpler no matter the backend. For instance, you can setup a simple server forward controller if you aren't using a reverse proxy. And it makes modeling your apache rewrite rules simple. For instance:

RewriteEngine On
RewriteRule ^/ajs/(.+)$ /index.html

That said, I haven't seen the directory/fallback method before, so am interested to explore it for when the only rewrite I need is for the angular forward. Thanks!

Comments

0

This is a slight variation and elaboration of Scott Ferguson's excellent answer. I find it easier to use the <Location> directive than <Directory>. The <Directory> directive takes an absolute path name which can be different in different machines.

So, let's say that your Angular app's index.html is in my-app/index.html under the document root of your web server. And you wish to access the app using http://localhost/my-app.

First of all make sure that your base href is "/my-app/". Next, in your httpd.conf file add:

<Location "/my-app">
    FallbackResource /my-app/index.html
</Location>

This will cause Apache to load index.html if any resource under /my-app/ can not be found.

If you are making API calls under the same path, such as say /my-app/api then you should probably not apply the FallbackResource rule for these calls. So add:

<Location "/my-app/api">
    FallbackResource disabled
</Location>

Comments

0

From my production server:

<VirtualHost *:80>
        ServerName XXX.com

        DocumentRoot /home/www/XXX.com/www

        # Local Tomcat server
        <Location /api/>
          ProxyPass http://localhost:8080/api/
          ProxyPassReverse http://localhost:8080/api/
        </Location>

        RewriteEngine On

        # If an existing asset or directory or API is requested go to it as it is
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d [OR]
        RewriteCond %{REQUEST_URI} /api
        RewriteRule ^ - [L]

        # If the requested resource doesn't exist (and is not API), use index.html
        RewriteRule ^ /index.html

        ErrorLog logs/XXX.com-error.log
        CustomLog logs/XXX.com-access.log common
</VirtualHost>

Please note, that "!" before "/api" in the accepted answer is incorrect.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.