Remove Trailing Slash from Specific URL using HTACCESS - php

How to force remove trailing slash from specific URL using htaccess,
For example :
https://blahblah.com/checkout/?checkout=add_to_cart&id=17&item_options[price_id]=1/
to
https://blahblah.com/checkout/?checkout=add_to_cart&id=17&item_options[price_id]=1
and ignore other URL such as https://blahblah.com/about/ or https://blahblah.com/contact/ etc

Because the trailing slash is part of the querystring you can't just rewrite it, you have to extract the querystring minus that final / and then redirect to the page you're on with that match appended.
To do this you need to match on the pattern in the RewriteCond with %1 (see this answer for reference) and append that to the %{REQUEST_URI} (thus removing the original querystring) - like this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(.*)/$
RewriteRule ^.*$ %{REQUEST_URI}?%1 [L,R=301]
RewriteCond %{QUERY_STRING} ^(.*)/$ <-- make sure you've got that / at the end here in your conditional - it ensures that only querystrings that end with / are redirected so you don't end up in a horrible recursive loop.

You can try this:
RewriteCond %{QUERY_STRING} (.*)/$
RewriteRule ^(.*)$ /$1?%1 [L,R=301]
This will redirect every request containing query strings only. In your case this:
checkout/?checkout=add_to_cart&id=17&item_options[price_id]=1/
to
checkout/?checkout=add_to_cart&id=17&item_options[price_id]=1
But not this https://blahblah.com/about/ and https://blahblah.com/contact/

I would advise trying to find out why that trailing slash is there to begin with first. As CD001 said in the comments it could be that your PHP code is doing something wrong.
If however you do need a htaccess solution to remove the slash then the below should work for you.
RewriteCond %{QUERY_STRING} ^(.*)/$
RewriteRule ^(.*)$ ?%1 [L,R=301]
This has been tested at http://htaccess.madewithlove.be/ and works for your example URLs.

if you mean an internal routine
RewriteCond %{QUERY_STRING} ^(checkout\=[^\&\s]+\&id\=\d+\&item_options\[price_id\]\=\d+)\/
RewriteRule ^ %{REQUEST_FILENAME}?%1 [L]

Related

.htaccess mod rewrite help needed

I have written this little piece of code. I am very new to this so i am not sure it is all correct. but basically it lets me access urls with the php extension. When people get on the site they are being redirected from the geo ip page to the correct language which like looks like this
main.php?lang=uk or nl or en or eu etc.
right now i can also use it like this
main/?lang=uk or nl or en or eu etc.
I would like to be able to to also remove the variable in the url ?lang=uk.
How would i do this. My .htaccess code is below
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
DirectorySlash On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{SERVER_NAME}/$1 [R=301,L]
# remove trailing slash
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]
RewriteRule ^([\w\/-]+)(\?.*)?$ $1.php$2 [L,T=application/x-httpd-php]
</IfModule>
Thanks too anyone willing to help.
The first argument of RewriteRule does match anything after the domain name and prefix* and before any query string if that exists. In http://localhost/this/is/my/test?lang=123 with a .htaccess file in the this/is/ directory it would match my/test. To match a query string, you have to use the %{QUERY_STRING} variable.
If the second argument (the rewritten url) of RewriteRule does not contain a query string, it will automatically append the query string of the original url to the new url.
In the code below I use %{THE_REQUEST}. This is the string that is used to make the request for a page. It is in the form of GET /my/resource?query=string HTTP/1.1. It does not change when rewriting things, which makes it useful to prevent infinite loops.
In your php file make sure that the language is read from a cookie instead of a get variable, then do the following:
#Set cookie for language
RewriteCond %{QUERY_STRING} ^(.*?)&?lang=([^&]+)&?(.*?)$
RewriteRule ^ %{REQUEST_URI}?%1&%3 [CO=lang:%2:127.0.0.1:1:/:0:1,R,L]
#Remove potential prefix or suffix & from query string
RewriteCond %{QUERY_STRING} ^&(.*?)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*?)&$
RewriteRule ^ %{REQUEST_URI}?%1 [R,L]
#External requests with \.php should be without that.
RewriteCond %{THE_REQUEST} \.php
RewriteRule ^(.*)\.php$ $1 [R=301,L]
#Try to load php page if resource does not alreay have an extension
RewriteCond %{REQUEST_URI} !\.[a-z]+$
RewriteRule ^(.*)$ $1.php [L]

Mod rewrite only when directory exists

I have a directory structure as follows:
/gallery
----index.php
----/23XASDTAGH
----/24XGA43KJA/
I'd like to use mod rewrite to rewrite if a directory exists. so:
www.example.com/gallery/23XASDTAGH/
becomes
www.example.com/gallery/index.php?gallery=23XASDTAGH
but i'd like to do this silently, so no changes happen to the url. now i have this:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}/ -d
RewriteRule (.*) /gallery/index.php?gallery=$1 [L]
which works with
www.example.com/gallery/23XASDTAGH/
but the odd thing is when i leave the trailing slash off the end it changes the url to
www.example.com/gallery/23XASDTAGH/?gallery=23XASDTAGH
how can i get it to work with or without the trailing slash?
I think the following will do the trick
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) /gallery/index.php?gallery=$1 [L]
Second line checks that the requested filename is a directory and if it is then the third line does the actual rewrite
To try and deal with the trailing slash problem, maybe this, or something like this will work
RewriteCond %{REQUEST_FILENAME} (.*)/?$
RewriteCond %1 -d
RewriteRule (.*)/$ /gallery/index.php?gallery=$1 [R=301]
You may want to try this:
RewriteEngine on
RewriteRule ^(gallery)/([a-zA-Z0-9-_=]+)/?$ http://www.example.com/$1/index.php?$1=$2 [R=301,L]
Permanent redirect the entered URL (The one in the browser address bar):
www.example.com/gallery/23XASDTAGH or www.example.com/gallery/23XASDTAGH/to:
www.example.com/gallery/index.php?gallery=23XASDTAGH
Finally figured it out, i needed a ?/ at the end of my expression in the rewrite rule to say that the slash was optional. Why do regular expressions have to be so hard easy. 8-)
correct expression:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^([a-zA-Z0-9_-]+)?/$ /gallery/index.php?gallery=$1 [L]

How can I transform a query string generated by a search form into new URL without the query string?

I have a search form that on submit generates something like this url:
http://mydomain.com/index.php?find=some+text
And I'm aiming to make it look like:
http://mydomain.com/find/some+text
How can I do this with .htaccess ?
So far I have this:
RewriteCond %{REQUEST_URI} ^/index\.php$
RewriteCond %{QUERY_STRING} &?find=(.*)&?
RewriteRule ^index.php$ find/%1? [R=301,L]
RewriteRule ^find/(.*)$ index.php?find=$1 [L]
This works if the query (i.e what I search for) contains only numbers, letters or underscore, but I want to make it capable of search for anything including spaces and other characters!
So, it seams that the 404 error was being cause because of some configuration in the web server that did not permit URLs to have + (plus sign).
It would break at the first + and try to find a file by that name.
Having that sorted out the rewrite rules were like this:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /*.index\.php\?find=([^&\.]+)?\sHTTP
RewriteRule ^/?index.php$ /find/%1? [L,R=301]
RewriteRule ^/?find/(.*)$ /index.php?find=$1 [L,NC]
Thanks for your help!
Shouldn't something like this work?
RewriteRule ^find/([^/]*)$ /index.php?find=$1 [L]
You need to match against the actual request and not the URI because the URI gets rewritten via your second rule. This causes a redirect loop.
To redirect the browser:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\?find=([^&\.]+)(&([^\ ]+))?
RewriteRule ^/?index.php$ /find/%1?%3 [L,R=301]
To internally rewrite it back
RewriteRule ^/?find/(.*)$ /index.php?find=$1 [L,QSA]

my .htaccess redirection fails

htaccess is enabled, i have the canonicalization running (no-www to www.)
I'm trying to use htaccess to do the following
www.domain.com/page.php?i=Page1
www.domain.com/page.php?i=Page2
To
www.domain.com/Page1
www.domain.com/Page2
I tried using this code snippet, with no luck so far:
rewriterule ^([a-zA-Z0-9_-]+)/$ page.php?i=$1
However I think I'm going the reverse way. I can't find example for this.
I have this but I can't make it work.
Try this:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/page\.php$
RewriteCond %{QUERY_STRING} ^i=([a-zA-Z0-9_-]+)$
RewriteRule ^(.*)$ http://www.domain.com/%1? [R=302,L]
taken from: http://www.simonecarletti.com/blog/2009/01/apache-query-string-redirects/
You want www.domain.com/Page1 to be visible in the browser's address bar, but internally that url should actually /page.php?i=Page1. In that case the problem is the trailing / in your regex:
Rewriterule ^([a-zA-Z0-9_-]+)/$ page.php?i=$1
^---here
Your desired /Page1 url has no trailing slash, yet your rewrite regex requires one, so the pattern doesn't match, and no rewriting occurs. Try removing the / and see if that helps any:
Rewriterule ^([a-zA-Z0-9_-]+)$ page.php?i=$1
^---no /
In order to parse out the query string you need to access it in a RewriteCond
# We need this line because /page.php?i=page.php will cause an infinite loop
RewriteCond %{QUERY_STRING} !i=page.php
# Now we parse out the value of i from the query string
RewriteCond %{QUERY_STRING} i=([^&]+)
RewriteRule ^page.php /%1 [L]

Clean AND "dirty" url

I made a htaccess for clean urls that is processed by PHP after, however for my search option I want a youtube-like '?q=searchquery'.
RewriteEngine on
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule ^(.*)/$ index.php?d=$1 [L]
That's my htaccess and it works for all urls but 'http://www.website.com/search/?q=searchquery' doesn't. Now I've tried other rewrites such as these
RewriteRule ^(.*)/\?(.*)/$ index.php?d=$1&$2
RewriteRule ^(.*)/\?q=(.*)/$ index.php?d=$1&q=$2
They dont work.
I also had a look the entire URI using the [R] flag and everything from the question mark doesn't show.
RewriteRule ^(.*)/$ index.php?d=$1 [L]
Using the url: http://www.website.com/search/?q=searchquery displays: http://www.website.com/search/
Edit:
So how do I do both? \o/
Just use the QSA (Query String Append) flag:
RewriteRule ^(.*)/$ index.php?d=$1 [L,QSA]
If the URL is called with a query string, the query string is appended to the generated URL.
PS: You can't match a query string within the rewrite rule. The query string is stripped off, before the rules are matched.

Categories