RewriteRule not working fine - apache

I wrote the following rule in .htaccess
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)/$ profile.php?business=$1
When i enter the URL like
http://www.abc.com/mujeeb/
page is correctly transfered to profiles page and page looks fine.
But i enter this in URL
http://www.abc.com/mujeeb
page doesn't show.
Can you please tell why? Or write the rule for this? i tried many times but not sucessful.
Mujeeb.

page doesn't show. because you specified that you RewriteRule is applied to the URL's ending with / at the end. Rewrite it as
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]
And I hope that you have additional RewriteCond statements in order to prevent the infinite loop with redirects.
ps: basically you can prevent loop in two way
1) checks that requested url does not correspond to the existing file or directory. it is, probably, the best way to do (read comments to the second method)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]
2) checks that you are requesting not the file from RewriteRule. This method is not good, because for each request, even for existing files and directories, it calls profile.php script
RewriteCond %{REQUEST_URI} !profile\.php$
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]

It is because you check for the trailing slash with ^(.*)/$. If you add a question mark, the trailing slash will be optional.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)/?$ profile.php?business=$1
The RewriteCond is neccessary to make sure the Rule will only be applied once. Otherwise Apache will be caught in an infinite loop.

Try this:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)[/]?$ profile.php?business=$1
That makes the last slash optional.

Well you rule is checking for a trailing slash in URI and that's the reason /mujeeb/ works but /mujeeb does not. Change your code to:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
# If the request is not for a valid file
#RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid directory
#RewriteCond %{REQUEST_FILENAME} !-f
# your rule without trailing slash
RewriteRule ^(.*)$ profile.php?business=$1 [L,QSA]

Plenty of good answers already. My answer is a bit different.
This is what I usually do. If the requested URL doesn't end with a /, I make the browser redirect to a URL with the trailing /. This is consistent with the default behaviour of Apache (due to mod_dir). So, this is how I solve this problem.
RewriteEngine On
# Canonicalize http://example.com/mujeeb to http://example.com/mujeeb/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)([^/])$ /$1$2/ [R=307,L]
# Let profile.php process http://example.com/mujeeb/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ profile.php?business=$1

Related

MultiViews is *too* tolerant of bad URLs

When I enable MultiViews, if I visit bad URLs, the my page (index.php) is still reached, when I want the user to get a 404 error instead. I'm trying to figure out how to fix this without creating rules in my .htaccess.
For example, "www.mydomain.com/index/blah/blah", visits index.php, but I want it to fail due to the extraneous trailing garbage URL components. Similarly for "/contact/blah/awuihda/hiu", which shows the content of contact.php, should give a 404 error, because "/blah/awuihda/hiu" doesn't exist.
If I disable MultiViews it works fine, but then I can't abbreviate the URL as much as I want to (for example, can't type "/contact" to bring up "contact.php").
You could just use the following so the .php extension is not required, which is the usual approach:
RewriteEngine on
# Remove .php if it's present with a 301 redirect
RewriteRule ^(.+)\.php$ $1 [R=301,L]
# If a request doesn't exist as a directory, file or symlink
# and it does exist with .php appended, rewrite to that
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]
I know it's adding a rule to .htaccess but it's a one off that works for everything and also means you're not hitting potential duplicate content allowing the same thing to be served with or without .php (or indeed with anything at all trailing after it as in your examples). Hope it's useful.
It could go in main server config but would need altering.
I found a solution which works for me.
Options -Indexes SymLinksIfOwnerMatch -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Source: link

Adding exceptions to mod_rewrite

I got my basic redirects work with the mod_rewrite module. When requesting pages e.g. localhost/home it's correctly redirecting to localhost/index.php?page=home, but I have a problem with exceptions.
I created a folder api where I store files by category e.g. api/auth/register.php and api/customer/create.php. I tried to make rewrite rule that contains 2 params (in this example auth and customer) so basically it just drops the .php off from the url.
The rule that I made is following
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L]
After adding that line to my .htaccess, problems started to occur. For example my .css and .js files started to redirect. So maybe I need to make some exeption for the apis? Have you some other ideas to improve my rewrite rules?
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L] # problems started to occur after adding this line
RewriteRule (.*) index.php?page=$1 [L,QSA]
Thanks in advance.
RewriteCond will affect only the first following RewriteRule so you need the keep them next to your initial Rule, and move the added one above them (with its own conditions).
Also, your /api rule is not strict enough ((.*) will pick anything, including the slashes), which might not matter in you case, but still. I sugest you try with this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/([^/]*)/([^/]*)/?$ api/$1/$2.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?page=$1 [L,QSA]

.htaccess mod_rewrite not working correctly

I'm using Wamp on my dev machine to develop a project. This is my .htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]
RewriteBase /project/
This is put in localhost/project, so that any requests like localhost/project/something , are routed to localhost/project/index.php/something
However, they are being routed to localhost/index.php/something
I suspect it has something to do with how I'm using RewriteBase. How do I fix it?
You need to remove the leading slash in your rule:
# no slash---------v
RewriteRule ^(.*)$ index.php?$1 [L]
Apache kind of guesses whether the targets of a RewriteRule is a URL-path or a file-path. When it starts with a slash, it assumes it's a URL-path and that it's absolute, so it'll go to the document root's index.php. Without the slash, it'll either guess a file-path or use the rewrite base to help determine which to use.
You should also move the RewriteBase directive above your rule.
Why not put the base in the rewriterule?
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /project/index.php?$1 [L]
Edit:
This question might help you: htaccess RewriteBase

Apache mod_rewrite query string before page and remove extention

I've scavenged the web for answers to my mod_rewrite woes and I feel I'm at the end of my wits. I will have a URL like such: http://www.website.com/dashboard.php?username=stackoverflow. This url isn't the prettiest of such. So my goal is to do a few things here...
Eliminate the extension of the php file (I've been able to do this so far with the code I'll show below, but I don't know that it will stay according to the other things I need to do)
Eliminate the "www" prefix
Move the username query string (only if it's "username", I don't want to match "id" or such) directly after ".com/"
Move the php filename (without the extension) after query string.
The final URL should look like such: http://website.com/stackoverflow/dashboard or perhaps http://website.com/stackoverflow/profile.
The code I have right now which eliminates the file extension is such:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# remove .php ONLY if requested directly
RewriteCond %{THE_REQUEST} (\.php\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]
# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# rewrite to FILENAME.php if such file does exist and is not a folder
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ /$1.php [L,QSA]
Sadly this only fixes one of my issues and after looking at it, I'm getting the feeling there would be a better way to do this...
(1, 3, 4) As I understand you want to use pretty URLs, but backed by PHP pages. So it should be like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\w+)/profile$ /dashboard.php?username=$1 [L]
It will make http://website.com/stackoverflow/profile working as http://www.website.com/dashboard.php?username=stackoverflow
(2)
# Redirect www.site.com to site.com with 301
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

htaccess url rewrite help

I have the following rewrite URL:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rewrite all other URLs
RewriteRule ^(.*)$ index.php?page=$1 [PT,L]
Now I want to add an exception, that if the URL is something like mysite.com/abc it should ignore it and all things inside it also. mysite.com/abc/dfgs also should be excluded from this rewriting.
How can I accomplish this?
If /abc is an existing directory, you can put another .htaccess file in there with
RewriteEngine Off
If it's really just one string you want to not rewrite (whether it exists or not)
RewriteCond %{REQUEST_URI} !^/abc
will not rewrite if the requested path starts with "/abc"
To test rewrite rules without messing up the site for regular browsers (not that you should be editing in a live environment of course, this is purely hypothetical :-) ), I've found the following very helpful:
RewriteCond %{REMOTE_ADDR} 12.34.56.78 # <-- where that's your IP address
This should avoid rewriting if the URI contains abc. This may or may not be exactly what you want. If it isn't edit your question.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#Rewrite ONLY if the REQUEST does NOT contain abc
RewriteCond %{REQUEST_URI} !abc
# Rewrite all other URLs
RewriteRule ^(.*)$ index.php?page=$1 [PT,L]