htaccess redirect without user knowing - php

We are running multiple domains through the same code and we want to save their images in their respective folders. Here's what we are doing.
/images/www.domain1.com/logo.jpg
/images/www.domain2.com/logo.jpg
now, what I want to know is, is this possible in htaccess that we rewrite the urls without user suspecting anything. This is what I want that
<img src="/images/logo.jpg" />
should internally become through htaccess
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L,R=301]
But my question is,
The above redirect continually loops
Can I achieve the img effect without user or admin suspecting anything?
Sincerely,
Khuram

Remove the R=301 to simply do a rewrite rather than a redirect:
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L]
The reason it's continually looping is that the 301 redirect causes a new request to be created for the url images/www.domain1.com/logo.jpg. That URL also matches your ^images/(.*)$ rule, so it is redirected again, ad infinitum.
If you really want to do a 301 redirect (I suspect you don't, but if you did), you could solve the infinite looping problem by adding some rewrite conditions to skip the redirect if the domain is already included:
RewriteCond {REQUEST_URI} !^images/www.domain1.com/(.*)$
RewriteCond {REQUEST_URI} !^images/www.domain2.com/(.*)$
RewriteRule ^images/(.*)$ /images/{HTTP_HOST}/$1 [L,R=301]

You definitely should not use R flag if you don't want to change URL in browser. However even without R flag your RewriteRule will loop infinitely and you will eventually get internal server error. Use RewriteRule like this:
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^images/(.*)$ images/%{HTTP_HOST}/$1 [L,NC]
Which is using a special internal variable called {ENV:REDIRECT_STATUS} that is set to 200 once RewriteRule rule is applied successfully.

Related

Why is this .htaccess not silently redirecting?

Can anyone tell me why the following visibly changes the URL in the browser, rather than redirecting silently? The redirect works, but visibly.
Example URL: http://domain.com/_test/sportswire/uk/football/huddersfield
...visibily redirects with query string arguments showing.
RewriteEngine on
RewriteBase /_test/sportswire
#favour naked domain over www
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*) http://%1/$1 [R=301,NE,L]
#disallow trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
###THIS RULE### channel pages - territory/sport/channel/[res type?]
RewriteRule ^(\w+)\/(\w+)\/(\w+)(?:\/(\w+))?$ channel.php?territory=$1&sport=$2&team=$3&res_type=$4 [L,NC,R=301]
#channel pages - with item (if from external referrer) - territory/sport/channel/res_type/"item"/item_id/pretty
RewriteRule ^(\w+)\/(\w+)\/(\w+)\/(\w+)\/story\/\w{11}\/[^\/]+$ channel.php?territory=$1&sport=$2&team=$3&res_type=$4&item=$5 [L,NC,R=301]
What I've tried/read:
Remove the R flag (no joy; and I have other .htaccess files with R flags that redirect silently)
Add/remove a rewrite base (done; also tried an absolute one)
Don't use absolute URLs (I'm not)
I'm fairly convinced there's nothing on planet earth quite as perplexing as mod-rewrite.
Try removing the [R] flag altogether, so that the server won't notify the browser of the change.
htaccess changes take effect immediately, so you don't need to restart the server. However, since you previously tried R=301, your browser may remember to go straight to the URL with the query string and never even ask the server for the URL you're trying to redirect. To see the effect of the change I recommended, start a new browser instance in incognito or private browsing mode and test the new rule.
Side note: why are you escaping all the / in your paths? I don't think you need to.
[R] flag should not be there. Try restarting Apache if that is possible, I've noticed that it helps sometimes.
Try another browser or different URL, they can cache redirects.

Subdirectory not redirecting to index

I used the following code in my .htaccess file.:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
After using it, it finally allowed me to remove file extensions, my goal,
but then subdirectories no longer redirected to their respective index files,
instead showing just 'Forbidden' and '404' messages.
I then tried to make manual redirects in the .htaccess:
Redirect 301 /subfolder http://www.domain.com/subfolder/index
Which then got me stuck in redirect loops, and even after removing them in the source code, they have carried on. I should also point out that I have almost no experience in using .htaccess.
Welcome to the wonderful world of testing with permanent redirects: Make a mistake, and it continues making the error until you clear the browser cache.
First of all, remove the redirect, and clear the cache of your browser. Second of all, imagine that your rules are applied to every request, not just the requests you want to change.
The problem you identified was a request to a directory matching your rule, then getting rewritten. Requests to http://domain.com/sub/ would be rewritten to http://domain.com/sub/.php. Now that is not anything that exists. The only thing saving you from infinite recursion is your check for dots in the url.
So, how do we fix that? Well, we check if the requested file is not a directory to start of. Now we don't rewrite the url if it is a directory, and DirectoryIndex takes care of the rest. To prevent infinite recursion, you can test if the url already ends with .php, but in this case you already took care of that.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Try with this redirect. It got stuck in a loop because 301 is a permanent redirect and it gets saved in the browser.
RedirectMatch 301 /subfolder(.*) //$1

.htaccess Apache mod rewrite rule always giving a redirect loop

I am normally fine at writing apache redirects but this particular client's server has been giving me problems :c
I am trying to redirect all sub-pages to the main domain but I am always getting a infinite redirection loop.
Here's my .htaccess file - what am I doing wrong?
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^test$ "http\:\/\/example\.com\/" [R=301,L]
RewriteCond %{REQUEST_URI} !"^/$"
RewriteRule ^.*$ "http\:\/\/example\.com\/" [R=301,L]
whoa redirect infinity! but say if I do something like this:
RewriteRule ^test$ "http\:\/\/example\.com\/" [R=301,L]
This will redirect http://example.com/test to http://example.com and bam, it works!
Any guidance would be appreciated. Thanks!
// EDIT
The issue is that we have a mailing list plugin which sends the user a confirmation email. After clicking the confirmation button in the confirm email the user is redirected back to our site with a long query string appended to http://example.com/. The query string is generated so it's never going to be the same.
Here's an example of one of the query strings:
http://example.com/?has_media=false&fan=https%3A%2F%2Fapp.topspin.net%2Fapi%2Fv1%2Ffan%2Fshow%2F63451204%3Fartist_id%3D12053%26auth%3D96419cab29f59a342cde9ca3c0c20b58&campaign=https%3A%2F%2Fapp.topspin.net%2Fapi%2Fv1%2Fartist%2F12053%2Fcampaign%2F10151864
// Edit 2
I tried #Jon Lin's example and the page loads strangely but it does load. Basically, the correct domain loads in some browsers but the assets (CSS, and images do not) and the networks inspector is showing these paths as permanently moved also :s
Try changing your last rule to:
RewriteRule !^(?:index\.(html?|php)|)$ http://example.com/ [R=301,L]
The reason is that after the directory index is mapped (to something like index.php), the rules get reprocessed again, and thus the extra redirect.
Note that the query string is still going to be at the end. That's because there is no way to match against the query string in a RewriteRule. You need to match against the %{QUERY_STRING} variable. In order to get rid of the query string, you need to add a ? to the end of http://example.com/.

How to write an htaccess 301 Redirection rule to redirect from php to html

I have a problem (it's probably a simple one but I've never had the need to write regex)
A SEO specialist told me to make pretty URLs so I did with the .htaccess file the CMS provides.
But now he requires me to redirect the old URLs to new ones.
This doesn't work
RewriteRule ^index.php?page=kontakt$ /kontakt.html [R=301,L]
and also this (wich was supposed to redirect to the main page from the index.php file)
RewriteRule ^index.php$ / [R=301,L]
has resulted in sitename.com/?page=kontakt, so now I also have to redirect this.
How do I fix this?
RewriteRule only matches the base URL without the query string. You need an additional RewriteCond for it to work.
RewriteCond %{QUERY_STRING} ^page=kontakt$
RewriteRule ^index.php$ /kontakt.html [R=301,L]
EDIT:
Apparently query string gets preserved in this case, so you're probably getting /kontakt.html?page=kontakt
To discard original query string you need to put ? after URL.
RewriteRule ^index.php$ /kontakt.html? [R=301,L]

Rewrite url which redirects to page on webserver

I am trying to get a page with a query string to redirect to a nicer looking url then get that url and transfer it back to the original query string but without redirecting (i.e. without changing the url)
At the moment I am getting a redirect loop (for obvious reasons) but I was hoping for a way to stop this.
This is my code in my htaccess file
#rewrite search querystring
#/search/'apartment'/2_bedrooms/price_0-500000/town_W4/development_18,SW5/
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) /search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
/search/$1/$2_bedrooms/price_$3-$4/town_$5/development_$6 [R,L]
RewriteRule ^(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6? [R,L]
So what it is meant to do is:
user has been taken to:
http://www.domain.com/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
This page is the actual page on the server where the data is coming from, however I want the user to see.
http://www.domain.com/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
Is it possible to do this without a redirect loop.
Thanks for your help
EDIT I'm thinking it could be done with the rewrite flags but I'm not sure, I'm quite new to the Rewrite Engine
Edited:
Here is a complete (and working) solution for you:
RewriteEngine On
# User gets here:
# http://localhost/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
# He is explicit redirected to here:
# http://localhost/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
# Internally, apache calls this:
# http://localhost/search.php?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC,PT]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
RewriteRule ^search/(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6/? [R,L]
It assumes you put .htaccess in server root and that there is a file search.php in root too.
Original:
I think you can use PT and QSA Rewrite Rule flags (http://httpd.apache.org/docs/current/rewrite/flags.html) in your first rule
Use PT for server-side redirection (it will not change the URL for the user/browser, but will for your server-side scripts)
Use QSA if you wanna carry the query while doing this redirection
You can redirect all requests that don't target an existing file to a specific php-script, for example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [PT,QSA]

Categories