rewrite everything except files and directories - html

i want to create a .htaccess rewriting rule for everything except existing files or folders, but cannot figure out what the problem seems to be.
My Code now is this.
RewriteEngine on
RewriteCond %{REQUEST_URI} !(-f|-d)$
RewriteRule .* index.html
i dont want to create a rule for everything except the allready existing files and folders in case i create aything else on the server.
the rewriting works properly but the exeptions do not.

the right code for this need is
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f #exeption for files
RewriteCond %{REQUEST_FILENAME} !-d #exeption for dirs
RewriteRule .* index.html

Related

Remove .html extension in url

Today I tried to remove html file extension from my website, for example:
example.com/page.html to example.com/page
I watched some tutorials, but nothing seems to work...
I created .htaccess file in root directory
Copied code (also tried different ones):
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html [NC,L]
It didn't work when I opened my website as file, with Live Server (VS Code extension) or actual website (hosted on Replit)
Any idea, why it doesn't work? Any help appreciated...
See whole repository
Edit: Someone said, I have to remove .html file extension. I get error that the file is not found
Yo should do it in this way:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC, L]
SOLVED
As someone said, .htaccess file doesn't work on Replit. I've done following:
Made folder for every .html file
Moved that file inside of the folder I made
Renamed the file to index.html

remove html extension using htaccess file

i know this is a very common topic but none of the solutions works for me.
i have tried several answers:
answer 1
answer 2
answer 3
and the referal links.
The htaccess code that i am using:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ /$1 [L,R=301]
then i changed my links from services.html to services i.e. i removed the extension and also removed the extension from the file name using ftp.
what i get is the page code displayed in my browser not the actual page.
I have checked mod_rewrite on my server and it works correctly using this code
RewriteEngine On
Options +FollowSymLinks
RewriteRule ^joomla\.html http://www.joomla.org/? [R=301,L]
Your file should still have the .html extension on the server, otherwise the server/browser won't interpret it as html but text instead (which is the reason you see the code in your browser). So rename the files on your server using ftp again.
In order to let your server serve the file /test.html when the url /test is accessed, you want to rewrite that internally, i.e.:
RewriteRule ^test[^/]$ test.html
The ^ is to match the start of the string, the $ matches the end, so this will only rewrite if the url exactly matches test. It will rewrite that request to test.html. The rewrite is internal, this means it won't redirect the browser (the url in the address bar doesn't change). There is also the external rewrite ([R] appended to the rule), which redirects the browser.
This rule also only matches urls that don't end with a trailing slash ([^/] means "not slash"). We will handle urls with a trailing slash later.
You could create a custom RewriteRule for each page that you want to rewrite:
RewriteRule ^foo[^/]$ foo.html
RewriteRule ^bar[^/]$ bar.html
This is a lot of work if you have many pages, so you may want to rewrite all urls, e.g. foo or bar should be rewritten to foo.html / bar.html, and foo/bar should be rewritten to foo/bar.html.
You can also use a regular expression to match all requests. But you should first check if foo isn't actually a directory (which could contain a index.html and be a sub-directory you want to serve). Also you want to check if foo isn't really a file on your server's file system. There are two rewrite conditions to check that (see the RewriteCond directive):
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
Now you can add a rewrite rule for all requests:
RewriteRule ^(.+[^/])$ $1.html
$1 is the content of the first capture group, a capture group in a regex is an expression placed in () brackets. . matches any character, the + modifier means "one or more".
Note that this would cause a rewrite loop resulting in a 500 error (see this answer), so you need to also add a rewrite condition to check if the <request>.html file actually exists on the file system:
RewriteCond %{REQUEST_FILENAME}.html -f
Also you might not want to rewrite urls that already have a .html extension. I don't think it's necessary, as you already have the rule above which would in that case check for <file>.html.html which probably shouldn't exist. But if you have to deal with that, you could add another condition:
RewriteCond %{REQUEST_FILENAME} !^.+\.html$
So putting it altogether your rewrite rule looks like this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !^.+\.html$ # not really necessary
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+[^/])$ $1.html
The only thing that you need to handle now are urls that have a trailing slash. For that we just add a simple external rewrite rule that removes the trailing slash if the url doesn't actually match a directory:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
This rule matches only urls that end with / (regex /$) and captures everything before the trailing slash as a group (regex (.+)), then redirects to the group (which doesn't contain the slash). Notice the R and L flags behind the rule. R is for redirect, which redirects the browser (url in address bar changes). L is for last, meaning no other rules will be applied after this one, though rules will be applied again after the rewrite, and this is where the other rule gets applied.
TL;DR
RewriteBase /
# handle trailing slashes (if not a directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
# rewrite rule that internally adds the .html extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+[^/])$ $1.html
like #simon suggested the correct file is:
# handle trailing slashes (if not a directory)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ $1 [R,L]
# rewrite rule that internally adds the .html extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteCond %{REQUEST_FILENAME} !^.+\.html$
RewriteRule ^(.+[^/])$ $1.html
also i had to delete all text files with the same name from the server through ftp.

Moving From Development to Live Site breaks CSS

Using CodeIgnitor to manange this site I have configured the css in the following location:
{link rel="stylesheet" type="text/css" href="<? echo base_url();?>application/assets/css/public.css" />
Firebug shows me that the link points exactly where it should, unfortunately,
The problem is I keep getting 403 errors when it tries to load it.
my .htaccess file looks like this, and by the way, I don't really know what I'm looking at here:
RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt|application/assets/js|application/assets/css|application/assets/images)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
RewriteCond $1 ^(images|js|css)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./public/$1 [L,QSA]
How do I get this CSS to load?
Additional Info:
In that the assets folder there is also a js folder and an images folder and the favicon is NOT being pulled from that images folder either.
It sounds like the configuration on that folder and/or the server are refusing you access to read the file.
http://en.wikipedia.org/wiki/HTTP_403
Try navigating directly to the css file and you can easily confirm that you are getting a 403 error, if so it is to do with permissions.
Try accessing your development site remotely rather than from the same machine and you may see the same error there.

modrewrite to remove the file extension but still load the page

I have a subdomain with .php pages in it. I just want to remove the .php I have written some code gathered from other posts on stack, so far I have this
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} (\.php(.*)\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]
this rewrites
subdomain.example.com/weddings.php
to
subdomain.example.com/weddings
However it also creates a 404 page not found error. Am I doing something wrong?
Solved it. anyone struggling with the same thing here is my solution
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
found it on
http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
a fantastic website.

.htaccess rewriterule /state/city/

This will take a bit of explanation so I hope I don't lose everyone here.
I needed to get something like the following:
http://example.com/results.html?state=iowa&city=davenport
turned into:
http://example.com/iowa/davenport/
I was able to accomplish this with the use of these two rewriterules:
RewriteRule ^([A-Za-z0-9-]+)/?$ cities.html?state=$1 RewriteRule
^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ results.html?state=$1&city=$2
The problem is that in the backend there is "some code somewhere" that is getting broken as a result of the second rewriterule. It has to do with filling in a select box based on the results of another one selected (I don't think that matters though). I think the problem is in that I'm modifying too broadly the /state/city.
Here is a copy of my full (modified for security) .htaccess file:
IndexIgnore *
AddHandler application/x-httpd-php5 .html .htm
RewriteRule ^([A-Za-z0-9-]+)/?$ cities.html?state=$1
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ results.html?state=$1&city=$2
<Files .htaccess>
order allow,deny
deny from all
</Files>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
<IfModule mod_suphp.c>
suPHP_ConfigPath /home/USER
<Files php.ini>
order allow,deny
deny from all
</Files>
The code that its screwing up is very complex and its someone else's code. After a couple of hours I've been unable to wade through all of their stuff to even come close to what I may be able to change on their end to get things working.
Does anyone have ANY ideas on what I could do to avoid this problem? I really only have 3 .html files that I'm funneling my frontend code through so I had tried something like a
my rewriterules
and same with using just "files" instead of filesMatch. Everything I've come up with breaks something else or the entire site in one way or another.
First: (i) hostgator won't enable or give you access to rewrite logs; (ii) your suPHP config has syntax errors and hostgator almost certainly does spme of this and the .htacess / php.ini denials in its own root / vhost configs. However, I'll focus on the mod_rewrite elements:
RewriteEngine On
RewriteRule ^([A-Za-z0-9-]+)/?$ cities.html?state=$1
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ results.html?state=$1&city=$2
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
I am also assuming that you don't have any .htaccess files in subdirectories with the rewrite engine enabled as these could preempt this under rewrite "Per Directory" precedence rules.
Rules (3) is a simple domain redirector. Rule (4) is a draconian: redirect any URI which is not an existing file or directory to index.php in the current directory, but leaving the query string intact.
Rule (1) and (2) are your new rules. As Mike says, you should include the [L] but since the files cities.html and results.html exist it won't match anyway.
I am curious as to why the trailing slach in the URIs is optional. Better to decide and to fix this.
The issue is that the match criteria for (1) and (2) are two broad and are picking up URIs intended for the general catchall (4). You need to lock this down to make these mutually exclusive. One why is to mine your access logs (which are available with hostgator) to find the standard URIs which the application expects and check that none match (1) or (2) -- However, since most will include a ".", this probably isn't the case. But check.
The other issue is whether the existing scripts use absolute or relative references e.g. <img src="images/myimage.png"> in any output HTML. Here the browser has asked for http://www.example.com/texas/houston say and will therefore look for http://www.example.com/texas/images/myimage.png which doesn't match (1), (2) or (3) and therefore is caught by (4) and passed to /index.php. Ditto CSS files etc. Hence they won't 404 and index.php will get confused and send some default response which will hopelessly confuse the browser.
However, again analysis of the access logs (in this case or USIs with a referrer http://www.example.com/texas/houston) will show you if this is going on.
If your app uses standard subdirectories then you might be able to fix this by a rule (3.1) which looks something like
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $1/$2 -f
RewriteRule .*?(images|css|styles)/(.+) $1/$2 [L]
though the details will depend on the rest of your application.
I was able to solve it by changing my (relevant) .htaccess entries to the following:
RewriteEngine On
RewriteRule ^([A-Za-z0-9-]+)/?$ cities.html?state=$1
RewriteCond %{REQUEST_URI} !^/signup/
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ results.html?state=$1&city=$2
RewriteCond %{HTTP_HOST} ^example.com
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
The addition being:
RewriteCond %{REQUEST_URI} !^/signup/
HostGator was able to find that the issue was /signup somewhere in a log somewhere, never did find out which log they were able to look at but I assume it was something I didn't have access to.