HTACCESS: Rewrite a Previously Rewritten URL Causes Error - .htaccess

not sure what my problem is, but I insert one rewrite into my htaccess file and the whole thing breaks. I used an htaccess tester and it says the rule works fine.
For some reason Google indexed the php file that I normally rewrite URLs to. So I need to take the .php page that displays and send it to the proper rewritten URL.
Here is the rule:
RewriteRule ^products/Automotive-Transmission-Torque-Converters-results.php$ /Search-Results [QSA,R=301,L]
The only thing I can think that would be causing the problem, is that I use this URL in another rewrite later on in my code.
Here is the second rewrite later on in the file:
RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [QSA]
I hope I've identified the problem correctly. But again, I put the first rewrite rule into my htaccess and the the regular page doesn't show, the browser says there is an error on the page. Yet, htaccess testers say the rule works fine. Hence my suspicion.

RewriteRule ^products/Automotive-Transmission-Torque-Converters-results.php$ /Search-Results [QSA,R=301,L]
RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [QSA]
Yes, these two directives used together will result in a redirect-loop (something that online testers don't appear to check for). The problem is that the first rule will trigger an external redirect after the second rule has rewritten the URL (when the rewrite engine starts over - in .htaccess).
The solution is to make sure the first rule (the external redirect) only triggers on direct requests from the client and not requests that have been internally rewritten.
We can check for direct HTTP requests by checking against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to "200" (as in 200 OK HTTP status) after the first successful rewrite.
For example:
# Redirect direct request for PHP file to canonical URL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^products/Automotive-Transmission-Torque-Converters-results\.php$ /Search-Results [R=301,L]
# Internally rewrite the canonical URL
RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [L]
Note that I have removed the QSA from both rules, since it's not required here (the query string is appended by default). And I've included the L flag on the second rule. Also, don't forget to backslash escape the literal dot in the RewriteRule pattern.
Test first with 302 (temporary) redirect to avoid potential caching issues and make sure your browser cached is cleared before testing.
For some reason Google indexed the php file that I normally rewrite URLs to.
However, you need to try and identify how Google managed to find the PHP file/URL in the first place. If this is the a result of an incorrect internal link on your site then it needs to be fixed.

Related

Redirect all URLS to new URL EXCEPT for /backend/ with .htaccess

I want to redirect all incoming queries to a new domain, except for /backend
I have this in my .htaccess, everything works, except for the /backend. I tried a few combinations, it just doesnt work.
I fear /backend is a virtual address....
what can i do?
HERE IS THE CODE:
RewriteCond %{HTTP_HOST} ^example.de$ [OR]
RewriteCond %{HTTP_HOST} ^www.example.de$
RewriteCond %{REQUEST_URI} !^/backend/$
RewriteRule (.*)$ https://www.bing.de/ [R=302,L]
PLEASE HELP. Thank you. Patrick
I fear /backend is a virtual address....
In which case you most probably have other mod_rewrite directives that rewrite the request to a front-controller (such as index.php) - and that's the problem. Whilst your existing rule includes an exception for /backend/ (the originally requested URL), so the rule is skipped on the first pass by the rewrite engine, once the request is rewritten to the front-controller (eg. index.php) the rewrite engine begins a 2nd pass which results in the rule being successfully executed since the URL is now /index.php (or whatever your front-controller is) and not /backend/.
You either need to:
modify the other directives that rewrite the request to the front-controller, so as not to trigger a 2nd pass through the rewrite engine. (You've not included your complete .htaccess file, so I'll discount this approach for now.)
OR, make sure you only examine the originally requested URL and not the rewritten URL. (The REQUEST_URI server variable is modified as the request is rewritten.)
However, I would assume that your /backend/ page also links to static assets (such as images, CSS, JS)? In which case, you also need to make exceptions for any additional static assets that are used by the page, otherwise these will also be redirected. For the sake of this example, I will assume all you static assets are located in an /assets subdirectory.
Try the following instead, near the top of your root .htaccess file:
RewriteCond %{HTTP_HOST} ^(www\.)?example\.de [NC]
RewriteCond %{THE_REQUEST} !\s/backend/\s
RewriteRule !^assets/ https://www.bing.de/ [R=302,L]
Note that this rule must go before the rewrite to the front-controller.
The THE_REQUEST server variable contains the first line of the HTTP request headers and importantly, does not change as the request is rewritten. This contains a string of the form GET /backend/ HTTP/1.1 (containing the request method, URL and protocol).
If there are no external assets then change the RewriteRule pattern from !^assets/ to simply ^, to match everything.

htaccess int:tolower redirected many times

i have activate RewriteMap in Virtualhost with:
RewriteEngine On
RewriteMap lc int:tolower
... and after that in htacess have this role:
RewriteCond %{REQUEST_URI} [A-Z]
RewriteRule . ${lc:%{REQUEST_URI}} [R=301,L]
... but make me redirected many times and don't get my REQUEST_URI every time redirect me to /.
I don't have idea why don't get it (on my old hosting work fine) if anyone has an idea and can help? I will be very happy and thank you in advance!
There's nothing actually "wrong" with the rule itself, however, I suspect you have a conflict with other directives that internally rewrite the URL (that may occur later in the file). The REQUEST_URI server variable is modified when the URL is rewritten - so does not necessarily contain the originally requested URL on subsequent passes through the rewrite engine.
To ensure the rule is only processed on the initial request and not the rewritten request we can check against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to (string)200 (as in 200 OK status) after the first successful rewrite.
For example:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule [A-Z] ${lc:%{REQUEST_URI}} [R=301,L]
Your original condition that checked against REQUEST_URI is unnecessary since this same check can be performed more efficiently in the RewriteRule directive itself.
You should also ensure that this rule is near the top of your .htaccess file, before any existing rewrites, since we still use REQUEST_URI in the substitution string.
You will need to ensure your browser cache is clear before testing and test first with a 302 (temporary) redirect to avoid potential caching issues.

htaccess won't rewrite url

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^product/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([a-zA-Z]+)/$ product.php?id=$1&srl=$2&item=$3&page=$4&title=$5#titleProduct
When I hit f5 button for refresh, the URL remains and it's not rewrited. I tried to access with the "new" rewrited link, but it's not working.
Wow, that means I'm need to update every single file for the "new" rewrite? All files contains different hyperlinks with the "old" link. I thought if I write a .htaccess file, all url will automatically rewrite.
You're thinking of a browser redirect, that changes the address bar, a rewrite takes the nicer looking URL and internally rewrites the URI to something the server can understand. See the top half of this answer for a better explanation of this process.
So you can do a browser redirect if the browser actually requests the product.php file, then redirect to the fake nice looking URL. The browser will then resend a new request, for the nice looking URL and the server gets that, internally rewrites it back to the php file (the rule that you have).
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /product\.php\?id=([^&]+)&srl=([^&]+)&item=([^&]+)&page=([^&]+)&title=([^&\ ]+)
RewriteRule ^product.php$ /product/%1/%2/%3/%4/%5/ [L,R=301]
This will take a /product.php\?id=123&srl=abc&item=qwerty&page=blah&title=something URI and redirect the browser with a 301 to the nicer looking URL. Then you're rule should internally rewrite it back.
Regardless, you really should change the links you serve to the nicer URLs, relying on mod_rewrite to do both ends of the work is really inefficient.

HtaccessRules to redirect my website

Hi can anyone of you suggest me on how to redirect my page http://testsite.com/about.php to http://testsite.com/about/ by using htaccess rewrite rules.Without using any query string in the page url i need to rewrite it
I don't think you want a redirect but a rewrite. A redirect means informing the client to requery for the redirected url, whereas rewriting means telling the server to interpret an url as being some other url.
and you dont' want to rewrite about.php to /about/ but the other way around. You want your users to type in /about/ and that url to be handled by /about.php
and this is done by:
RewriteEngine on # this line enables rewrite
RewriteRule /about/$ /about.php
RewriteRule /about$ /about.php
I'm not sure if both of the above are actually needed or just one (I don't have access to an apache right now to test)
In the slight chance that you actually do want a redirect as you wrote, use this free redirect generator: http://www.htaccessredirect.net/ (it's easier than learning all the quirks of the conditions to match up)
in your case that will be:
Redirect 301 /about.php /about/

URL rewrite issues using .htaccess

I'm trying to write a URL like below, but when I try to call the seo queryparam, it always returns index.php. Any idea why it isn't returning the correct value for 'seo'?
RewriteRule ^([^/]*)$ index.php?c=home&m=details&seo=$1 [L]
The URL it should forward from would be something like this: http://domain.com/The-Name-of-the-Product. That URL should be rewritten to http://domain.com/index.php?c=home&m=details&seo=The-Name-of-the-Product, but instead it ends up as http://domain.com/index.php?c=home&m=details&seo=index.php
Various events cause a URL to go back through the rewrite process. You can use RewriteCond to prevent this:
RewriteCond $1 !^index.php$
RewriteRule ^/?([^/]+)$ index.php?c=home&m=details&seo=$1 [L,NS]
From the mod_rewrite technical details:
When you manipulate a URL/filename in per-directory context mod_rewrite first rewrites the filename back to its corresponding URL (which is usually impossible, but see the RewriteBase directive below for the trick to achieve this) and then initiates a new internal sub-request with the new URL. This restarts processing of the API phases.
This catches people all the time.

Resources