.HTACCESS - Prevention of 404 with no URL query - php

I'm using .htaccess to re-write some of my URLs for my web application. The following is used to make the user page a little prettier when user_urls (practically a URL friendly username) are passed to it:
RewriteRule ^user/([0-9a-zA-Z-]+) /user?url=$1 [NC,QSA]
When I input the URL http://example.com/user, the page redirects just fine, and the PHP handles the lack of the query string. However, when the server receives the request of http://example.com/user/, it returns a 404 error.
How can I prevent this from happening?
Thanks.

Redirect to the correct URL by prepending a rule
RewriteRule ^(.*)/$ /$1 [L,R=301]
or append /? to your regexp.

You can use these rules in your .htaccess:
Options -MultiViews
RewriteEngine On
RewriteRule ^user/?$ user.php [NC,L]
RewriteRule ^user/([0-9a-zA-Z-]+)/?$ user.php?url=$1 [NC,QSA,L]

Related

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]

htaccess redirection loose post data!! how to keep post data while redirect using htaccess?

I have a .htaccess file that rewrite .php to .htm:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]+\s([^\s]+)\.php\s
RewriteRule .* %1.htm [L,R=301]
RewriteRule ^(.*)\.htm$ $1.php
The redirect works fine, But the redirection looses the $_POST data. How to keep $_POST data while redirecting?
Browsers convert a POST request into a GET request on redirect. The RFC states that they should instead prompt the user if the method needs to change, but none of them follow that and instead force the method change unconditionally.
If you want to simply rewrite the URL from .php files to .htm files, all you'll need to do is something like this -
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]+\s([^\s]+)\.php\s
RewriteRule ^(.*)\.php$ $1.htm
The 3 lines of the .htaccess detail the flowing behavior -
Turn on the rewrite engine
The request matches the given regular expression.
Rewrite the entire URL to use a .htm file.

404 page when no match found

i have this rewrite rules:
RewriteEngine on
RewriteBase /
RewriteCond %{THE_REQUEST} \.php[\ /?].*HTTP/ [NC]
RewriteRule ^.*$ - [R=404,L]
RewriteRule ^(home|contact|about|submit|search)/?$ /index.php?page=$1 [L]
RewriteRule ^([a-z]+)/([a-z0-9-]+)/?$ /index.php?page=home&cat=$1&slug=$2 [L]
RewriteRule ^([a-z]+)/?$ /index.php?page=home&cat=$1 [L]
What i want is:
if user types something which is not matching last three conditions i want to show a 404 error. At present it loads home page. So i am check $_GET['page'] in there. I donot want to check in php.
do you have anything to improve my rewrite rules or any additions?
please help
Since everything is ultimately routing to index.php (Front-end Controller Pattern), I suggest dropping the the mod_rewrite and using:
FallbackResource /index.php
Then parse the URL in index.php and handle routing accordingly.
This will take some rewriting, but will be more flexible in the long run.
Read more about FallbackResource and Front-Controllers in PHP.
You may use mod rewrite to add argument to your web page index.php, then treating them in the php page possibly sending back a error page (as in cakePHP). that keeps only ONE rule.
RewriteRule ^([0-9A-Za-z]+)/?$ /index.php?argument=$1 [L]
Try to use ErrorDocumentwhit location page
ErrorDocument 404 /erreur_404.html

Forcing urls to rewrite/redirect?

This rewrite methode works, but its not Forcing urls to rewrite/redirect to the new urls.
I use this:
RewriteEngine on
RewriteRule ^page/([^/\.]+)$ search.php?q=$1
i can access rewrited urls (project/page/etc..) , but old urls/links (search.php?q=etc) still accessible without redirect.
note: i use $_SERVER variants to creating urls, and on localhost.
You have to rewrite project/page to search.php? in order to hide the ugly urls.
And redirect search.php? to project/page in order to make the canonical urls the only way to access that resource.
In your code there is no mention of the redirect, you're just rewriting.
Think of it this way
rewrite hides the ugly urls behind canonical urls (it hides them, it doesn't eliminate them);
redirect responds to the browser with a message like "search.php? has moved to project/page, try that link instead" and the browser follows the new link;
To redirect so called ugly URLs to SEO friendly URL you would need another Rewrite rule. Have your .htaccess code like this:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteRule ^page/([^/\.]+) search.php?q=$1 [L,QSA,NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+search\.php\?q=([^\s]+) [NC]
RewriteRule ^ page/%1? [R=302,L]
Once you have verified that it's working fine change R=302 to R=301.
You'd need a [R=301] on the rewrite rule to turn it into a client-side redirect. Otherwise it's purely an internal rewrite and the client will never see the url getting changed.
e.g.
RewriteRule ^page/([^/\.]+)$ search.php?q=$1 [R=301,L]

Categories