.htaccess does not open index - apache

I decided to do a little rewriting on my site.
Currently, I have this htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
What it does is that you can enter .php documents without adding the .php extension
, like
you can access folder/file.php by typing folder/file into the url bar.
However, now I realised that index.php is not working anymore.
If I try to enter the index via folder/index.php or folder/index, it works fine but it does not open it when typing just folder/
What rule am I missing here?
Sorry I'm not used to htaccess. Thanks for your help.

...but it does not open it when typing just folder/
Presumably you just get a 404?
You should also exclude directories from being internally rewritten. For example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
So now, when you type example.com/folder/ (which maps to a directory, not a file), it won't be rewritten by the above directives and mod_dir will be able to load the DirectoryIndex.
Aside: There is an additional caveat with having the same content accessible by all these different URLs (eg. folder/index.php, folder/index and folder/) - you now have a potential duplicate content issue. Be sure to be consistent in you internal linking, include canonical meta tags and redirect if it becomes a problem.

Related

Started implementing .htaccess but when navigating from the reduced URL, when going into a directory it then can't get back

So I have included an htaccess file to my server in the root directory and changed all of the ./ I could find set the absolutes.
However, when I search by URL into one of the directories pressing the home button does not take me home. Instead, it appends the index onto the end:
/website/book/index.php?p=home
Instead of
/website/index.php?p=home
Where have I made a fuddle?
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+[^/])/$ https://%{HTTP_HOST}/paperbound/$1 [R=301,L]
RewriteRule ^([^/\.]+)?$ index.php?p=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)$ index.php?p=$1&id=$2 [NC,L]
</IfModule>
Is the htaccess used. https://sitehost/website/book/2 is URL entered and page retrieved which exists as https://sitehost/website/index.php?p=book&id=2, clicking navlink to return to https://sitehost/website/index.php?p=home, instead places https://sitehost/website/book/index.php?p=home into the URL bar and returns an error as the file does not exist.
With your shown samples/attempts, please try following htaccess rules file. Make sure to keep your index.php file is present in website folder and htaccess is present along side with website folder(not inside it).
Please make sure to clear your browser cache before testing your URLs.
##Enabling rewrite engine here.
RewriteEngine ON
##Checking conditions for non-existing pages here.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
##performing internal rewrite here to index.php file.
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/?$ $1/index.php?p=$2&id=$3 [QSA,L]

.htaccess two query string cannot link to original folder

Here is the file structure of my web
css/
script/
images/
.htaccess
index.php
ajaxusername.php
.htaccess content
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(\w+)/(\w+)$ index.php?d=$1&t=$2 [QSA]
RewriteRule ^(\w+)/?$ index.php?d=$1
When input http://www.abc.com/peter/, it can translate into http://www.abc.com/index.php?d=peter successfully.
When i input http://www.abc.com/peter/password, it can translate into http://www.abc.com/index.php?d=peter&t=password successfully too.
The problem is:
/peter/ can get the resources listed in above folders successfully but,
/peter/password cannot get those resources.
When I checked in firebug, it shows me it points to http://www.abc.com/peter/css/user.css, which is an invalid URL.
The correct URL must point to http://www.abc.com/css/user.css instead the previous one.
Any suggestion? Thanks!!
Problem is that you're using relative paths for css, js and images and once you start using pretty URL scheme of /part1/part2 it messes up URLs of your resources. As you've noted that css URI becomes /peter/css/user.css instead of /css/user.css.
Here are some solutions for you to help.
Solution 1: To overcome your issue I recommend using absolute path in your css, js, images files rather than a relative one. Which means you have to make sure path of these files start either with http:// or a slash /.
Solution 2: It is no doubt better to use absolute path for static files (css, js, images etc). But if you have lots of those instances in several pages then consider using HTML base tag to specify a default URL for relative paths. eg:
<base href="http://www.abc.com/" />
Solution 3: mod_rewrite based solution. Use it when you can't implement above solutions.
Have you .htaccess like this:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't do anything for a real directory, file or link
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule - [L]
# your original rewrite rules
RewriteRule ^(\w+)/?$ /index.php?d=$1 [QSA,L]
RewriteRule ^(\w+)/(\w+)/?$ /index.php?d=$1&t=$2 [QSA,L]
# rules to fix wrong paths of css, js and images
RewriteRule ^[^/]+/((?:css|script|images)/.*)$ /$1 [L,R=301,NC]
It looks like you need to add exceptions to your rewrite rules for requests to files and directories that exist on the server, otherwise when the files are requests by the client's browser they won't be served since the url is rewritten.
Try adding these lines:
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? - [S=2]
into your htaccess file:
Options +FollowSymlinks
RewriteEngine on
...put them here...
RewriteRule ^(\w+)/(\w+)$ index.php?d=$1&t=$2 [QSA]
RewriteRule ^(\w+)/?$ index.php?d=$1
And your resources should be accessible.

RewriteCond Being Ignored?

I am trying to use mod_rewrite on a Ubuntu 12.04 server to make my URLs more readable, however I want to add an exception for images and css files.
My input URLs are in the format \controller\action which is then re-written to index.php?controller=controller&action=action. I want to add an exception so that if an image or css file is specified, the URL is not re-written, e.g. \images\image.jpg would not be re-written.
My .htaccess code is as follows:
RewriteEngine on
RewriteCond %{REQUEST_URI} !(\.gif|\.jpg|\.png|\.css)$ [NC]
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)$ test.php?controller=$1&action=$2 [L]
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)/([^/]*)$ test.php?controller=$1&action=$2&$3 [L]
My re-write code is working fine and the URLs are coming out as intended, however even if I request an image, the URL is still being re-written. It appears that my RewriteCond is being ignored, anyone any suggestions as to why this might be?
The RewriteCond only applies to your first RewriteRule, it should be reproduced for the second rule. However, I think that is better to add a non-rewriting rule, before, to exclude existing stuffs.
# Do nothing for files which physically exist
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
# your MVC rules
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)$ test.php?controller=$1&action=$2 [L]
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)/([^/]*)$ test.php?controller=$1&action=$2&$3 [L]
The rewriteCond rule is only applied for the next RewriteRule.
So you need to at least repeat the rewriteCond for your seconde RewriteRule.
No there is certainly better things to do.
For example a usual way of doing it is to test that the url is matching a real static ressource. If all your php code is outside the web directory (in libraries directory, except for index.php) then all styatic ressources available directly on the the document root can only be js files, css files, or image files.
So this is the usual way of doing it:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)$ test.php?controller=$1&action=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([a-zA-z]+)/([a-zA-z]+)/([^/]*)$ test.php?controller=$1&action=$2&$3 [L]
But this is a starting point. We could certainly find something to avoid doing 2 rules for this (maybe I'll have a look later)

Redirect sitename.com/en to sitename.com/ar using htaccess file

I want to redirect sitename.com/en and all links inside that sections to the same urls with /ar instead of /en using htaccess file. The number of links inside the section is enormous, so I can't write them one by one. Please help...
Use this .htaccess :
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^en/(.*)?$ /ar/$1 [QSA,L]
If you want that old pages (en/) to no longer be used, and see the new url (ar/) in your browser, use [QSA,L,R=301] instead of [QSA,L] (it notify you're using a permanent redirection)

How to hide the .html extension with Apache mod_rewrite

I have a small number of static sites where I simply want to hide the .html extension:
the URL /foo fetches the static file /foo.html
the browser still displays the URL /foo
The client can then send out bookmarks in the style example.com/foo rather than example.com/foo.html.
It sounds very simple, and I've used mod_rewrite happily before (say with WordPress or for redirects), but this is proving much harder to crack that I thought. Perhaps I'm missing something really obvious, but I can't find a solution anywhere and I've been at it all day!
We run our own server, so this can go wherever is the best place.
Addendum
The solution checked below worked fine. Then after running the site awhile I noticed two problems:
all pages began to appear unstyled. I reloaded, cleared the cache, etc., but still no-style. I've had this trouble before, and can't locate the source.
There's a directory AND an HTML file named 'gallery', so the /gallery link shows a directory listing instead of the HTML file. I should be able to sort that one, but further tips welcome :-)
Try this rule:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]
This will rewrite all requests that can be mapped to an existing file when appending a .html.
The previous answers don't check if the requested path is a directory.
Here is the full rewrite condition which doesn't rewrite, if requested path is a directory (as stated by the original question):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f # is an existing html file
RewriteRule ^(.*)$ $1.html # rewrite index to index.html
To be SEO friendly and avoid double content, redirect the .html URLs:
# Redirects example.com/file.html to example.com/file
RewriteCond %{REQUEST_FILENAME} !-d # is not directory
RewriteCond %{REQUEST_FILENAME}\.html -f # is an existing html file
RewriteCond %{REQUEST_URI} ^(.+)\.html$ # request URI ends with .html
RewriteRule (.*)\.html$ /$1 [R=301,L] # redirect from index.html to index
If you need the same for scripts take a look here:
How can I use .htaccess to hide .php URL extensions?
The accepted solution do not works when the website is configured with a virtual host / document root.
There is the solution I used:
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_FILENAME}.html [L]
Look at this post http://alexcican.com/post/how-to-remove-php-html-htm-extensions-with-htaccess/ I haven't tried it yet but the demonstration seems pretty convincing.
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Wow, I have seldom seen such an issue for which there exists so many "solutions" on the web, where people just throw up what "works for them" but for which few take time to read the documentation to figure out what it does. Many of the solutions given here don't work for virtual hosts, for example.
After much cross-referencing and reading, I want to contribute my own solution that "works for me". Hopefully it works for you, too. I didn't create it from scratch; I was inspired by all the other contributions (even though most of them did not "work for me" without modification).
RewriteEngine on
#if foo requested, return foo.html contents
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.html -f
RewriteRule ^(.*)$ $1.html [L]
#redirect foo.html to foo
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^(.+)\.html$ $1 [R,L]
The [R] flag by default does a temporary (302) redirect; if you want a permanent redirect, use R=301 in place of R.
To remove .html extension from .*.html requests, you can use the following script in root/.htaccess :
RewriteEngine On
RewriteBase /
#1) externally redirect "/file.html" to "/file"
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html [NC]
RewriteRule ^ %1 [R=301,L]
#2) rewrite "/file" back to "/file.html"
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*?)/?$ $1.html [NC,L]
the url /foo fetches the static file /foo.html
the browser still displays the url /foo
Apache can do this without mod_rewrite, see documentation:
Multiviews
The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's requirements.
Source: http://httpd.apache.org/docs/current/content-negotiation.html
Here is an example which allows us to store the file on disk as:
foo.html.php
But in the browser, refer to it as
foo.html
To make this work for you, I think you would just need to modify it a bit to match your existing requests, and check for an actual file in place with the .html extension.
# These are so we do not need the .php extension
RewriteCond %{REQUEST_FILENAME} (\.xul|\.html|\.xhtml|\.xml)$',
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}.php -f',
RewriteRule ^(.*)$ $1.php',