.htaccess redirect everything except certain request - php

I am having an issue with my .htaccess file. It is redirecting everything through my index.php page which is what I want for the majority of requests.
BUT the only time I do not want to redirect is via an AJAX call.
It redirects any request through my index.php file like so:
RewriteRule /.* /index.php [NC,L]
The AJAX request url is:
http://myurl.dev/login/ajax/functions.php
With the directory structure:
/modules/login/ajax/functions.php
I am inexperienced with regex and RewriteRules, and have read / tried many variations with varying logic but cannot stop anything from /ajax/ to not redirect to the index page.
I have tried a RewriteCond before the Index RewriteRule to redirect to index unless /ajax/ but no luck.
Rewrite Cond %{REQUEST_URI} !(.*)/ajax
RewriteRule /.* /index.php [NC,L]
Also tried a seperate RewriteRule for the /ajax/ request:
RewriteRule ^(.*)/ajax/functions\.php$ /modules/$1/ajax/functions.php [NC,L]
So nothing as worked so far, it either redirects to the index or hits a 500 server error.
Does anybody have any suggestions or links to help? Thanks.
Note: When I say redirect, I do not mean a full page refresh as I know that Apache wont do a full url refresh without the [R] flag.
-- Edit: Working file --
Here is my full .htaccess code:
Options +FollowSymLinks
RewriteEngine on
# Intercept any requests to the core, and keep them being written to the core (so they don't go to index.php)
RewriteRule ^core/(.*)$ core/$1 [NC,L]
# The magic, stops any requests to a file for being redirected.
# needed to be under the /core/ redirect
RewriteCond %{SCRIPT_FILENAME} !-f
# Rewrite all requests to index.php.
RewriteRule /.* /index.php [NC,L]
# Some requests (without trailing slashes) can fall through the above rule. This bit catches those stragglers.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
ErrorDocument 404 /404/

Use
RewriteCond %{SCRIPT_FILENAME} !-d //excludes existing directories
RewriteCond %{SCRIPT_FILENAME} !-f //excludes existing files
before any RewriteRule . This will exclude any directory or file which already exists, so the RewriteRule won't work on http://myurl.dev/login/ajax/functions.php, because it actually exists, but it will work on http://myurl.dev/someOtherNonExistantFile.php
That makes this your full .htaccess file code:
AuthType Basic
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
# Intercept any requests to the core, and keep them being written to the core (so they don't go to index.php)
RewriteRule ^core/(.*)$ core/$1 [NC,L]
# Rewrite all requests to index.php.
RewriteRule /.* /index.php [NC,L]
# Some requests (without trailing slashes) can fall through the above rule. This bit catches those stragglers.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]
ErrorDocument 404 /404/

Related

Creating a re-direct for 404 pages

I created a 404.php page and added the following in my .htaccess file
ErrorDocument 404 /404.php
Also played around with removing the slash, adding a full URL, etc,
No matter what I do, I get my index.php UI regardless to what I write in the URL. Here is the thing, IT IS NOT re-directing me to domain.com/index.php or "/". The URL remains, but the UI is the index.php content
I'm adding my re-direct below in case you see something there that is conflicting
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
From what I know of the mod_rewrite the last 4 lines are saying
That if the request filename is not a file nor a directory,
redirect to index.php.
And this is what is happening I believe.
All of the routes that are not available on the physical path in your application are going to index.php.
You will need some 404 mechanism in your application. If you are using some framework it usually has an exception like "RouteNotFound" thrown and then error handler redirects to a 404 page, you can also do something similar and redirect from within your application to 404.php.
if($should_be_an_error) {
header("Location: 404.php");
}
(haven't used something like this for years but should be something similar)
or remove
`
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
`
But then your other routes might stop working.
EDIT:
Since you wanted to redirect to 404.php instead of index.php(getting that from comments) the code should be changed to
RewriteRule . /404.php [L]
(last line of the rewrite block)
You can do this using FallbackResource directive. Remove all the code starting with RewriteBase / line and use this single line:
FallbackResource /404.php
This will fallback to /404.php for any 404 event.
You can see this code below as an example if it match your requirement:
ErrorDocument 404 http://example.com/404/
RewriteCond %{REQUEST_URI} ^/404/$
RewriteRule ^(.*)$ /404.php [L]

Why does my rewrite rule only work on specific word?

I need a rewrite rule, which rewrites every request to index.php, except when the word web is in the url. So, every image, JS, CSS file is located under the web folder. Here are my .htaccess file which currently does the trick:
<IfModule mod_rewrite.c>
RewriteEngine On
# Folders / files to exclude from rewrite divided by Pipe goes here:
RewriteRule (^|/)web(/|$) - [L,NC]
# turn empty requests into requests for "index.php",
# keeping the query string intact
RewriteRule ^$ index.php [QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !favicon.ico$
RewriteRule ^(.+)$ index.php [QSA,L]
RewriteRule ^(.+)$ index.php [QSA,L]
</IfModule>
This works for:
http://localhost/~alpham8/application/index/index/
http://localhost/~alpham8/application/
http://localhost/~alpham8/application/index/someaction/
http://localhost/~alpham8/application/web/img/someimage.png
But it does not work for:
http://localhost/~alpham8/application/somecontroller/someaction/
The none-working URLĀ“s returns me an 404 error.
Please help me.

htaccess redirect if folder exists else redirect to another folder

I would like to redirect with htaccess to a certain folder 'setup' if it exists.
Else it must do the stock standard redirect as it was :
RewriteEngine on
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ http://%{HTTP_HOST}/$1 [L]
RewriteBase /
RewriteRule ^$ /site [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /api/index.php [L]
Now my htaccess-Fu are not nearly where it supposed to be. I read the posts I could find on SO but none of them helped for my specific case.
Then I have a sub-question: Is it bad practice to have this permanently in your htaccess file? Seeing as it would only exist the first time you setup the site?
I often see people doing this via PHP, but doing it via htaccess does seem like a great alternative!
So what you're looking for is something like:
RewriteEngine on
# The part your looking for: If setup is present and you're not in it redirect there!
# If the setup directory exists in the document root...
RewriteCond %{DOCUMENT_ROOT}/setup -d
# ...and you're not in setup..
RewriteCond %{REQUEST_URI} !(setup) [NC]
# ...redirect to setup - with a 302 (temporary redirect) to make sure the browser won't cache the redirect.
RewriteRule ^(.*) /setup [L,redirect=302]
# the rest of your htaccess should go here... for instance:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

.htaccess not rewriting the URL correctly for .php files, but OK for .html files

I'm trying to accomplish 2 things in my .htaccess:
Redirect all requests for (in example) www.blanklabs.com/boarddrive/faq, www.blanklabs.com/boarddrive/faq.htm, www.blanklabs.com/boarddrive/faq.html, or www.blanklabs.com/boarddrive/faq.php to www.blanklabs.com/boarddrive/faq.php
The browser's address bar should show just www.blanklabs.com/boarddrive/faq, without the extension.
Here is my current .htaccess:
RewriteEngine On
# -- new
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ $1.php [L,QSA]
On the server I have faq.html (for now), but I also tried having both faq.html and faq.php. Eventually it'll just be faq.php.
The .htaccess is clearly incorrect, since if I go to www.blanklabs.com/boarddrive/faq.html I get the correct content (from faq.html), but if I go to www.blanklabs.com/boarddrive/faq.php I get a 500 error. This happens even if I have faq.php on the server.
Any ideas what I'm doing wrong? The no-extensions is secondary, the primary goal is to redirect all requests from html to php files.
Place this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
# skip POST requests
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^ - [L]
RewriteCond %{THE_REQUEST} \s/+(.+?)\.(php|html?)[\s?] [NC]
RewriteRule ^ /%1 [R=301,L,NE]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)(\.html?)?$ /$1.php [L,QSA]
You need to redirect
/faq.htm
/faq.php
[using redirect directive]
to /faq
now just applying rewrite rule to this later condition [/faq] to
/faq.php
It should work.

Using .htaccess, never show index.php

How can I never show index.php? For example, all requests to
site.com/index.php/controller are redirected in the browser address bar to
site.com/controller?
My current .htaccess removes index.php but when a user directly types site.com/index.php/controller they are still shown that address in the address bar as opposed to site.com/controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
NOTE: Before flaming, I have checked lots of .htaccess threads that solve redirecting index.php but I haven't found one to never show index.php. Here are a few...
Not Show index.php in subdirectory
remove index.php in codeigniter
Try adding the following to your .htaccess file in the root of your domain
RewriteEngine On
RewriteBase /
#if you get a request for this /index.php/controller
RewriteCond %{REQUEST_URI} ^/index.php/controller$
#redirect to just controller
RewriteRule . controller [R=301,L]
If you need this to work for any path_info use the rule below instead
RewriteEngine On
RewriteBase /
#if you get a request for this /index.php(any-path)
RewriteCond %{REQUEST_URI} ^/index.php/(.+)$
#redirect to any-path
RewriteRule . %1 [R=301,L]
Try:
RewriteEngine On
RewriteBase /
RewriteRule ^index.php(.*)% ^/$1 [QSA,R]
I have not tested this, but as I understand it, it will take an URL with index.php as the filename (regardless of anything following it) and redirect it to /(.*) (i.e. anything that followed index.php in the original request). The QSA flag appends the query string, and R makes it a hard Redirect rather than just rewriting the URL on the current request.
For anyone looking for a more generalized solution:
Options +FollowSymLinks -MultiViews
#Disallow listing contents of subfolders
Options All -Indexes
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# If index or index.php requested, strip and redirect
RewriteCond %{THE_REQUEST} index(\\.php)?
RewriteRule ^index(\\.php)?$ http://yourdomain.com/ [R=301,L]
## Part 1
## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
## Part 2 - handle incoming that lacks extension (except for existing folders)
## To redirect /dir/foo to /dir/foo.php, (skip for admin or user dirs)
RewriteRule ^(admin|user)($|/) - [L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [L]

Categories