apache.htaccessmod-rewrite

How to use .htaccess to route requests to different file types and folders


To give some context. I have created a simple PHP MVC application and Im getting HTML output in the console from file types such as CSS, JS and images. It appears the application is returning the default view to the css/js file request.

My folder structure looks like this:

- app
- public
  - css
  - js
  - img
- index.php
- .htaccess

All requests should go to the index.php file to be routed etc. However, obviously I want all the css, js and img files to be served as they are.

My .htaccess

<IfModule mod_rewrite.c>    
  Options +FollowSymLinks
  RewriteEngine On

  RewriteCond %{REQUEST_URI} !-f
  RewriteCond %{REQUEST_URI} !-d
  RewriteCond %{REQUEST_URI} !-l
  RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

</IfModule>

Any advice on how to route the file requests back to the browser instead of the default view would be grateful.


Solution

  • RewriteCond %{REQUEST_URI} !-f
    RewriteCond %{REQUEST_URI} !-d
    RewriteCond %{REQUEST_URI} !-l
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
    

    You're using the wrong server variable in your conditions. You should be using REQUEST_FILENAME here, not REQUEST_URI. REQUEST_FILENAME is the computed absolute file-path that the URL maps to, whereas REQUEST_URI is simply the requested URL-path. Consequently these (negated) conditions will always be successfull and every request will be routed to index.php.

    In other words, it should be like this:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule (.+) index.php?url=$1 [QSA,L]
    

    You should also omit the the <IfModule> wrapper, since these directives are not optional. (Better to get an error - that you can act on - if mod_rewrite is not available, rather than silently fail with a nonsense 404 response.)

    Minor tweak, but I changed the regex from ^(.*)$ to (.+) (notably the quantifier from * to +) since requests for the root directory will fail anyway because of the directory condition. (Requests for teh root directory are reliant on the DirectoryIndex directive.)

    I am assuming your CSS, JS and image files have the appropriate file extensions, otherwise that would cause an incorrect mime-type issue as mentioned in comments.