.htaccess infinite loop for non existent urls - .htaccess

I'm working on my .htaccess to obtain an extensionless site. I've searched online and implemented some rules that are working, but when I type in a url that doesn't exist (e.g. mysite.com/dsfadfasdf ) it starts to go in an infinite loop.
If anyone would be so kind as to help me get rid of the loop and perhaps redirect to a page of my choosing (where I'll say the page doesn't exist) I'd really appreciate it!
Options +FollowSymLinks
Options +Indexes
RewriteEngine On
RewriteBase /
# Redirect www to non www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# Home page language
RewriteRule ^(en|ro)/?$ index.php?lang=$1 [L]
# For the profile page
RewriteRule ^(.+)\/accommodation-(.+)\/([0-9]+)\/(.+)$ location.php?id=$3&town=$2&hname=$4&lang=$1 [NC,L]
# Internally rewrite extensionless URL to corresponding .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ $1.php?%1 [NC,L,QSA]
# Externally redirect (only) direct client requests for .php URLs to extensionless URLs:
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.#?\ ]+\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php http://mysite.com/$1 [R=301,L]
I believe the issue is in the last rule. Any suggestions?

.htaccess keeps rewriting if the url changes. Force it to stop rewriting after you've rewritten your url internally with the END flag:
# Internally rewrite extensionless URL to corresponding .php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*)$ $1.php?%1 [NC,END,QSA]
Documentation is here.

Related

How can I redirect a single segment url without forward slash at the end?

My website's htaccess file is not allowing a single segment's redirect without a forward slash at the end. If I leave it off, it loops and crashes the website. How can I allow my users to go to [site].com/winter-camping and have it be redirected? This is what I have set up that currently works:
RewriteEngine On
RedirectMatch permanent /find-a-park/ https://[site].com/about/find-a-park
RedirectMatch permanent /winter-camping/ https://[site].com/about/promotion-details/winter-camping
#our rules:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
Basically I don't want my users to have to put the forward slash at the end to get to the page at all.
I do have instances that do work, however, which is why I'm confused. The only difference is they're subpages:
RedirectMatch permanent /parks/about/central-park https://[site].com/parks/central-park
One thing to know is that we use ExpressionEngine as our CMS. How can I get those first two redirects to redirect their urls and not crash my site? Thanks 🙃
You should use only mod_rewrite rule and use a regex with optional trailing slash:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^find-a-park/?$ https://[site].com/about/find-a-park [L,NC,R=301]
RewriteRule ^winter-camping/?$ https://[site].com/about/promotion-details/winter-camping [L,NC,R=301]
# Removes index.php from ExpressionEngine URLs
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{REQUEST_URI} !/system/.* [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,NE,L]
# Directs all EE web requests through the site index file
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>

htaccess force https non-www in single redirect for all pages

I would like to redirect everybody to my https:// site (not https://www) and force HTTPS in single redirect. My relevant parts of .htaccess:
# Check if HTTPS and WWW
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [OR,NC]
RewriteCond %{https} off
# Force HTTPS and remove WWW
RewriteRule ^(.*)/$ https://example.com/$1 [R=301,L]
The problem? It doesn't work for sub-pages!
While it does work for main page (eg. http://www.example.com redirects to https://example.com), it doesn't work for sub-pages (eg. http://www.example.com/contact sholud redirect me to https://example.com/contact but only www is removed and I end up on non-https site: http://example.com/contact).
How to change my .htaccess rules, to force HTTPS and remove WWW for my site and all pages of the site in single redirect?
After changes: it works for sub-pages, but in 2 redirects. Can it be done in only one?
Thanks to answer by Nisarg and some digging, my site now properly redirects to HTTPS even on sub-pages. Yay!
Relevant .htaccess code now looks like this:
RewriteEngine On
RewriteCond %{HTTPS} =off [OR]
RewriteCond %{HTTP_HOST} !^example\.com$
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]
# remaining htaccess mod_rewrite CODE for WordPress
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Unfortunately, it takes 2 steps to process. So, the question is still up: can it be done in 1 redirect?
Try the following:(Guessing you are using index.php)
RewriteEngine On
# Redirect to www
RewriteCond %{HTTP_HOST} ^[^.]+\.[^.]+$
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%1://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
#
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
#
# If the requested path and file is not /index.php and the request
# has not already been internally rewritten to the index.php script
RewriteCond %{REQUEST_URI} !^/index\.php
# and the requested path and file doesn't directly match a physical file
RewriteCond %{REQUEST_FILENAME} !-f
# and the requested path and file doesn't directly match a physical folder
RewriteCond %{REQUEST_FILENAME} !-d
# internally rewrite the request to the index.php script
RewriteRule ^ index.php [L]
Make sure you clear your browser cache before testing this change.

Dropzone.js does not work because of htaccess URL rewrite

My htaccess file is interfering with the implementation of Dropzone.js on my website. Here is the htaccess file:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
#Force non-www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
Options -Indexes
Basically I am forcing a non-www redirect and am hiding the .php extension from the URL. However, I did not know that that would interfere with Dropzone.js, which requires a file name in the action attribute of the form or in the url property of the Dropzone object.
How can I hide the .php extension without interfering with Dropzone.js?
Thanks to everyone! I took out the .php extension from the action attribute and like Enyo suggested that fixed it.

Rewrite a dynamic url after extension removed

I've been working on my HTAccess for a couple days now, and I've hit a dead end.
I've rewritten and redirected the files to be extensionless, now I need to rewrite the url to be SEO Friendly.
Previously, the URL was: http://www.example.com/member.php?playername=encodedName
I removed the extension: http://www.example.com/member?playername=encodedName
I can't quite get it to: http://www.example.com/member/encodedName
Here's what I've gotten so far:
Code trying to redirect to SEO Friendly URL. Does NOT work.
RewriteRule ^member/([^/]*)$ /member.php?playername=$1 [L]
RewriteRule ^squad/([^/]*)$ /squad.php?squadname=$1 [L]
RewriteRule ^article/([^/]*)$ /article.php?articlename=$1 [L]
Unless directory, remove trailing slash. Works.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
Resolve .php file for extensionless php urls. Works.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
Redirect external .php requests to extensionless url. Works.
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^/]+/)*[^.#?\ ]+\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(([^/]+/)*[^.]+)\.php $1 [R=301,L]
Does anyone have an idea as to what I am doing wrong? It's probably a very newbie problem that I just haven't encountered yet.
The "Code trying to redirect to SEO Friendly URL" part looks fine. And while you're redirecting requests made directly to php files to remove the extension, you're not doing anything specifically about the 3 SEO friendly URLs that you are rewriting back.
If when you go to http://www.example.com/member/encodedName, and you're not being served the content at http://www.example.com/member.php?playername=encodedName, then this looks like a Multiviews problem. You'll need to turn off Multiviews either in your server/vhost config or add this to the top of the htaccess file (or in the appropriate already existing Options statement):
Options -Multiviews
In order to do the redirecting to the SEO friendly URLs, add this before the "Redirect external .php requests to extensionless url." rules:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /member\.php\?playername=([^&\ ]+)([^\ ]*)
RewriteRule ^ /member/%1?%2 [L,R=301]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /squad\.php\?squadname=([^&\ ]+)([^\ ]*)
RewriteRule ^ /squad/%1?%2 [L,R=301]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /artcile\.php\?articlename=([^&\ ]+)([^\ ]*)
RewriteRule ^ /article/%1?%2 [L,R=301]

.htaccess, URL changes but loading content

I'm having an issue with .htaccess where I have managed to successfully rewrite the URLs but the content is no longer loading.
The following is my htaccess file.
I'm aiming for all my .html pages (the site is made of .html static pages) to have their extensions removed. However, I require the .html URLs to 301 redirect to the new URL's so that my SEO does not take a hit from these changes.
Example:
Original: www.example.co.uk/page.html
Desired: www.example.co.uk/page/
It is important that the original URL redirects the new URL's though.
Options +FollowSymLinks
RewriteEngine on
# REDIRECT yourdomain.com TO www.yourdomain.com
RewriteCond %{HTTP_HOST} !^www.example.co.uk$ [NC]
RewriteRule ^(.*)$ http://www.example.co.uk/$1 [L,R=301]
RewriteRule (.+)\.html?$ http://www.example.co.uk/$1/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(([^/]*/)*[^/.]+)$ $1.html [L]
I have tried the htaccess above and I've also tried the variation below, but neither has worked as desired. Any help would be much appreciated.
Options +FollowSymLinks
RewriteEngine on
# REDIRECT yourdomain.com TO www.yourdomain.com
RewriteCond %{HTTP_HOST} !^www.example.co.uk$ [NC]
RewriteRule ^(.*)$ http://www.example.co.uk/$1 [L,R=301]
RewriteRule (.+)\.html?$ http://www.example.co.uk/$1/ [R=301,L]
You need to change 2 things.
Add this right after your redirect to prevent a redirect loop:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
change the last rule to this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/(.*?)/?$
RewriteCond %{DOCUMENT_ROOT}/%1\.html -f
RewriteRule ^ /%1.html [L]

Resources