Trying this again because I realize how very poorly I worded my original post.
I have a page, Product1.php, that is dynamic for populating my products from a database.
This is the rubric of my SEO-friendly urls:
http://www.example/category/subcategory/model_name-model_id/product_id
This is the original url with query string that it rewrites to:
http://www.example.com/Product1.php?=Product_ID=1
This is the rewrite function I have in htaccess that makes this happen:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^category/.*/.*/([0-9]+)$ Product1.php?Product_ID=$1 [L,QSA]
However, if a user manually-types in http://www.example.com/Product1.php?=Product_ID=1 in the address bar, this is the one they still see. Moreover, it's the same for the search engine bots, which is dividing the value of my pages.
How do I write a 301 redirect that will force the user and bot to see the SEO-friendly url only, regardless of how they access the page? I have researched for days and various solutions I have tried give me only 404 or 500 errors.
Please help. Thanks in advance.
**EDIT: OK, looks like I can't invoke RewriteMap because I don't have access to my host's config files. (Need to upgrade our account to do so and employer is unwilling.) So will have to do a Rewrite Rule for each individual page, which is unfortunate but doable.
But still need to find out how to force the redirect with causing 404 or 500 errors. Anyone?
I used a little trick adding an "Internal" parameter to a rule responsible for main rewrite, and the check of this parameter in the 301 redirect. The solution with environment variables is also allows to process requests where the parameters may be presented in any order.
RewriteEngine on
# perform collecting parameters from query string to an environment variables
RewriteCond %{QUERY_STRING} Category=([^&]+)
RewriteRule . - [E=category:%1]
RewriteCond %{QUERY_STRING} SubCategory=([^&]+)
RewriteRule . - [E=subcategory:%1]
RewriteCond %{QUERY_STRING} Product_ID=([^&]+)
RewriteRule . - [E=productid:%1]
#...etc...
# give a right 301 redirect
RewriteCond %{REQUEST_URI} Product1.php
# make sure it's not an internal redirect
RewriteCond %{QUERY_STRING} !^Internal=1(.*)$
RewriteRule . /%{ENV:category}/%{ENV:subcategory}/%{ENV:productid}/? [L,R=301]
# now rewrite rule with the additional "Internal" parameter to label it as an internal redirect
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ([^/]+)/([^/]+)/([^/]+)
RewriteRule .* Product1.php?Internal=1&Category=%1&SubCategory=%2&Product_ID=%3 [L]
Thus, the following request
/Products1.php?Category=cat1&SubCategory=subcat1&Product_ID=321
will result in 301 redirect to
/cat1/subcat1/321/
and the appropriate page will be shown.
One more way is to remove the "Internal" trick and use another name of the script, Products2.php for example. I.e. you need something to distinguish external request from internal rewrite. to avoid infinite loop ("too much redirects" error).
Related
I'm sorry about the title but I can't find a good one to explain what I try to do.
I have my website : http://domaine.com .
The index.php file in it redirect to http://domaine.com/views/index.php .
Now I want to Rewrite Rule so that any url like :
http://domaine.com/something display the site http://domaine.com so that :
http://domaine.com/php redirect http://domaine.com/php/views/index.php
http://domaine.com/java redirect http://domaine.com/java/views/index.php
http://domaine.com/ruby redirect http://domaine.com/ruby/views/index.php
etc.
EDIT : I'm working on localhost so it's supposed to:
localhost/formation/php => localhost/formation/php/views/index.php
localhost/formation/java => localhost/formation/java/views/index.php
localhost/formation/ruby => localhost/formation/ruby/views/index.php
EDIT : The content of my htaccess:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*)$ views/index.php [L,QSA]
When I access to localhost/formation/ruby/ for exemple it's working but after the loggin it look like it's always redirecting from the home page to login page to home page etc.
EDIT : I create a repertory called "ruby" and create in it a htaccess file with that content.
RewriteEngine On
RewriteRule ^(.*)$ ../$1 [L]
And it does exactly what I want. So I want to find a way to do that without having to create the repertory "ruby".
http://domaine.com/php redirect http://domaine.com/php/views/index.php
http://domaine.com/java redirect http://domaine.com/java/views/index.php
http://domaine.com/ruby redirect http://domaine.com/ruby/views/index.php
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/(php|java|ruby)/$
RewriteRule ^.*$ /%1/views/index.php
I suppose by "redirect" you mean "serve as". In case if you want a 301 redirect, use the appropriate flags for RewriteRule, e.g. [R=301,L].
Wrapper
In case if you are trying to implement a wrapper script which is supposed to handle different request URIs, you should process the requests with a single script and pass the URI path parts as query string parameters. For instance:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/(formation|another_type)/(php|java|ruby)/$
RewriteRule ^.*$ /wrapper.php?type=%1&lang=%2
With this configuration, you can handle requests like http://your-site.com/formation/ruby/ with a single script. You can access the query string parameters using the $_GET superglobal variable, e.g. echo $_GET['lang'];.
Ultimately, you can process all requests with a single wrapper:
RewriteRule ^.*$ %{DOCUMENT_ROOT}/wrapper.php
Within the wrapper you will have to examine the contents of the $_SERVER superglobal. The REQUEST_URI and REQUEST_URI values are particularly useful.
I'm working on a website that has been built sloppily.
The website is filled with regular links that are translated into the corresponding .php pages by the .htaccess page.
This is it:
RewriteEngine on
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
First of all, I would love some help regarding whether or not this page has everything it should. I've never messed with it before.
Secondly and my main issue, if, for example, I would write the address www.thewebsite.com/foobar.html, it would be translated into www.thewebsite.com/cat.php?cat=foobar by the .htaccess page, and it would give a database error (and reveal information about the database).
I've put a check into cat.php which checks if the category exists, but I can't redirect the user to the 404 error page. There's a page called 404.shtml in the website, but redirecting the user to it causes the .htaccess to just change it again to cat.php?cat=404.
Is the way they used the .htaccess page normal? Should I change this system?
And how are users sent to error pages? From what I understood the server should be doing it on its own?
I would love some clarification... There is some much about this subject I don't understand.
Update:
This is my new .htaccess page
RewriteEngine on
RewriteRule ^error.php?err=(.*)$ Error$1.html
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
Because the redirecting is in the code and the user cannot see it, I allowed myself to write the link in a non-clean way. I tried turning it into a clean URL but the following does not do anything:
RewriteRule ^error.php?err=(.*)$ Error$1.html
Can someone please help me understand why? I thought since error.php is a real page, I should put it before the conditional but it didn't work. BTW, I saw in an article about .htaccess that the page should start with Options +FollowSymLinks. It seems to me that everyone sort of has their own way of writing it. Is there a guide or something like that, which I can be sure is authentic and covers all the bases there is about .htaccess?
Thank you so much!!
Using rewrite rules to work around links to .html pages that don't exist is unusual in my experience, but it's really just a different take on "pretty" URLs, e.g. www.thewebsite.com/foobar/ gets routed to cat.php?cat=foobar on the backend.
Your 404 issue is different. You need to be able to display error pages.
One option here is to rewrite requests as long as they don't request an existing file. This is very common for serving up static content like images, CSS files, and the like. To do this, you can use the -d and -f options to RewriteCond, which apply when requesting a directory and file respectively:
RewriteEngine On
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
Now, requests to 404.shtml should go through, because you're requesting an existing file on the filesystem.
Note that the RewriteConds only apply to the single RewriteRule that immediately follows. For additional RewriteRules, also include additional RewriteConds.
Your regex is wrong anywhere. Literal dot needs to be escaped using otherwise it will match any character. Also it is better to use L and QSA flags to end each rule properly.
RewriteEngine on
RewriteBase /
RewriteRule ^koral/([^/]+)/?$ page.php?name=$1 [L,QSA]
RewriteRule ^([^.]+)\.html/([^/]+)/([^/]+)/([^/]*)/?$ cat.php?cat=$1&page=$2&order=$3&dir=$4 [L,QSA]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
RewriteRule ^([^/]+)/([^.]+)\.html$ product.php?cat=$1&product=$2 [L,QSA]
I have re-written my URL from website.com?id=1 to website.com/1 and I'm getting 404 errors when trying to access the page and cannot think of a solution to this. I'm currently developing a link shortener. This is required so users will be able to access their shorted links.
This is my current .htaccessfile
RewriteEngine On
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /(index\.php)?\?id=([0-9]+)([^\ ]*)
RewriteRule ^ /%3?%4 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([0-9]+)/?$ /?id=$1 [L,QSA]
I cannot figure out whether this has something to do with the .htaccess file or if I need to add something else to my php code.
Would someone have some sort of idea? Thanks.
You need to explicitly rewrite back to index.php in your second rule. By the time rewrite rules are processed the DirectoryIndex directive has already been processed (or may never be processed at all - it depends a little on your virtual host configuration and in what scope the DirectoryIndex directive was declared).
The end result of this is that you need to explicitly rewrite the request to the script that you want to handle the request, you can't just rewrite it to the root of a directory. Try changing your second rewrite rule to:
RewriteRule ^([0-9]+)/?$ /index.php?id=$1 [L,QSA]
On a personal note, it's interesting to see someone else use the %{THE_REQUEST} approach to this problem, this is an idea that I myself only recently came up with, although presumably I am not the first to do so. For the benefit of future visitors, here is a related post that explains why this requirement would come about and the thinking behind it.
I think you have written wrong rewrite rules.
They must be something like this:
for example.com/website.php?id=x..
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=([^/]+)$
RewriteRule ^website\.php$ %1/ [L]
as discussed here: https://stackoverflow.com/a/4951918/2274209
Hope this will solve your query.
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]
Several days ago I had a question about removing index.php from the address bar, so the address of the page looks shorter and better. The shortest solution of this problem was (RewriteRule ^index.php / [L,R=301] in the .htaccess file). And it works!
Since I put that string into the .htaccess, some pages are redirected to the main page. I spent a lot of time to guess, why. As I understand, the answer is: with RewriteRule ^index.php / [L,R=301], $_POST parameters are not sent to the next page. $_GET parameters are OK.
Once I remove RewriteRule ^index.php / [L,R=301] from .htaccess, everything becomes fine as usual.
Why does it happen and how to fix that?
Thank you.
The [R] flag will incur a redirect. And user-agents issue a redirect as GET request. There is nothing that can be done if you really want to shorten URLs down to the / root path.
You could however block POST requests specifically from being rewritten/redirected:
RewriteCond %{REQUEST_METHOD} !POST
RewriteRule ^index.php / [L,R=301]
You could try using [L,R=307] instead. 307's must not change the request-method according to the spec, but I don't know how browser implemented 307.
But the root of the problem is the use of <form action="____/index.php" ...
Just leave the action empty to POST to the current url e.g.
I'm using something like:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(css|images|js)/
# don't rewrite existing files, directories and links
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# rewrite everything else to index.php
RewriteRule .* index.php [L]
</IfModule>
And its working for all requests, rewriting it via index.php file.
If you need to redirect 301 (which stands for Moved Permanently code) check out this question: Is it possible to redirect post data?
POST values will NEVER survive an external redirect (the R=301), it's a security liability, so browsers will never support that. Remove the R=301 and you will be fine. You just should alter all existing links to the page to the shorter/prettier one (<a>'s but also form actions etc.)
I had the same problems but my htacces was like this:
RewriteEngine on
RewriteRule .* index.php [NC]
Just change NC for L and everything works fine.
Final code:
RewriteEngine on
RewriteRule .* index.php [L]
In My case I used .htaccess.
Refer : PHP $_POST not working?
i.e
action="booking.php" to action="booking" worked for me