Removing trailing question mark with htaccess - .htaccess

Can someone help me understand this code?
# Remove trailing ?
RewriteCond %{THE_REQUEST} ? HTTP [NC]
RewriteRule .? /%{REQUEST_URI}? [R=301,L]
Basically I have a site www.example.com that is generating a link to www.example.com/index.cfm? I need it to redirect to www.example.com for SEO duplication purposes. I managed to remove the index.cfm but the ? still stays there (www.example.com/?). The trailing slash is also removed just fine if it's the last character. I found this rule online but I'm getting a "RewriteCond: bad flag delimiters" alert in apache and it doesn't do anything.
I also have some pages like www.example.com/index.cfm?term=test for searching so I just want to get rid of the trailing question mark and not when I do have a query attached to it.
The error is in the RewriteCond. I need help understanding the condition and why it doesnt work not just the answer to it.
Just in case here is the entire htaccess:
RewriteEngine On
Rewritebase /
# remove trailing index.cfm
RewriteRule ^index.cfm(\?)?$ / [R=301,L]
# SEF URLs
SetEnv SEF_REQUEST false
RewriteRule ^[a-z\d\-]+/[a-z]\d+/? /index.cfm/$0 [NC,PT,QSA,E=SEF_REQUEST:true]
RequestHeader add SEF-Request %{SEF_REQUEST}e
RewriteCond %{HTTP:SEF_REQUES} ^true$ [NC]
RewriteRule . - [L]
# Remove trailing ?
RewriteCond %{THE_REQUEST} ? HTTP [NC]
RewriteRule .? ^%{REQUEST_URI}? [R=301,L]
NOTE: I did search online/stackoverflow before posting and did not find a solution to my problem.
EDIT: Also I noticed that my RewriteRule ^index.cfm(\?)?$ / [R=301,L] is removing the index.cfm even if it's not the last thing in the url resulting in a 404 when i try searching something (www.example.com/index.cfm?term=test) If someone could correct me and EXPLAIN that would be great. Thanks you.
EDIT2: www.example.com/index.cfm?term=test&a=dh&j=dhjsi should NOT be redirected.
www.example.com/a/b/d/f/h/w/d should not be redirected.
www.example.com/index.cfm? and www.example.com/index.cfm should be redirected to www.example.com.

RewriteCond %{THE_REQUEST} ? HTTP [NC]
RewriteRule .? ^%{REQUEST_URI}? [R=301,L]
Isn't going to work, because ? is a reserved character for regular expressions and you'd need to escape it along with the space. Try:
RewriteCond %{THE_REQUEST} \?\ HTTP [NC]
RewriteRule ^/?(index\.cfm)? /? [R=301,L]
Additionally, you want this rule under your # remove trailing index.cfm rule, and not at the very bottom.

1) Case 1: removing question mark
http://example.com/page/subpage/?YOURSTRING=blabla
to redirect to
http://example.com/page/subpage/
then in the beggining of .htaccess, insert:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} YOURSTRING=(.*)
RewriteRule ^(.*)$ /$1? [R=301,L]
</IfModule>
# if wordpres isnot installed in root folder, then edit the fourth line to this
# RewriteRule ^(.*)$ /YOUR-WORDPRESS-DIRECTORY/$1? [R=301,L]
2) Case 2: redirection from question mark to another link
http://example.com/index.php?YOURSTRING=blabla&id=44
to redirect to
http://example.com/page/subpage/
Use:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} YOURSTRING=blabla&id=44
RewriteRule ^(.*)$ http://example.com/page/subpage/? [R=301,L]
</IfModule>

Related

301 redirect from URL with GET-parameters to the homepage

I have an old website with Joomla 1.5. It has some strange links with GET-parameters, like this:
http://www.primavista.ru/images/stories/catalog/?rand=1186511674
http://www.primavista.ru/images/stories/catalog/?rand=145388433
http://www.primavista.ru/images/stories/catalog/?rand=1553907057
http://www.primavista.ru/images/stories/catalog/?rand=1563973527
http://www.primavista.ru/images/stories/catalog/?rand=1981273478
http://www.primavista.ru/images/stories/catalog/?rand=2139631800
http://www.primavista.ru/images/stories/catalog/?rand=366928750
http://www.primavista.ru/images/stories/catalog/?rand=524689684
http://www.primavista.ru/images/stories/catalog/?rand=569077423
http://www.primavista.ru/images/stories/catalog/?rand=573405687
http://www.primavista.ru/images/stories/catalog/?rand=879649167
I want make redirect theses links to the homepage.
I tried some different instructions in .htaccess:
RewriteCond %{QUERY_STRING} ^/images/stories/catalog/?rand=([0-9]*)$
RewriteRule ^(.*)$ https://primavista.ru/? [R=301,L]
RewriteCond %{QUERY_STRING} ^/images/stories/catalog/?rand=(.*)$
RewriteRule ^(.*)$ https://primavista.ru/? [R=301,L]
RewriteCond %{QUERY_STRING} (^|&)(rand)=[^&]+ [NC]
RewriteRule ^images/stories/catalog(/.*)?$ https://primavista.ru/? [R=301,L,NC]
But no one not working. Maybe here someone can help me with this. Thanks
This probably is what you are looking for:
RewriteEngine on
RewriteCond %{QUERY_STRING} rand=\d+
RewriteRule ^/?images/stories/catalog/?$ / [R=301,L]
It is a good idea to start out with R=302 temporary redirections and to only change that to R=301 permanent redirections one you are satisfied with everything. That prevents nasty caching issues on the client side ...
UPDATE:
Your comment below indicates that you actually ask to remove the GET parameter in the redirected request, which you never mentioned before...
You can use the additional QSD flag for that:
RewriteEngine on
RewriteCond %{QUERY_STRING} rand=\d+
RewriteRule ^/?images/stories/catalog/?$ /? [R=301,QSD,L]

.htaccess and rewrite rule 404 not found

I'm new on .htaccess and rewrite rules.
So if my question is not relevant, please forgive me.
I have below htaccess code.
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
If i visit url like www.example.com/category/0 it works.
But if i strip page url and last slash www.exapmle.com/category i see an ugly 404 page.
What is wrong with my htaccess directive?
Thanks in advance.
EDIT: Compeletely .htaccess
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
## If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
## If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
## If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
## don't do anything
RewriteRule ^ - [L]
RewriteRule ^haber/([^/]+)-([^/]+)/?$ article.php?link=$1&i=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L,QSA]
This is a correct behaviour.
Actually, in a regular expression, a + means at least one.
When you use ([^/]+) it means at least one character which is not a slash.
Your rule ^([^/]+)/([^/]+)/?$ means at least one character which is not a slash / at least one character which is not a slash optional slash.
That's why it does not work with only the first part url.
If you also want to handle example.com/category you'll need another rule:
RewriteRule ^([^/]+)/?$ article-list.php?link=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/?$ article-list.php?link=$1&page=$2 [L]

Htaccess - Rewrite engine (reverse engineering a line of code)

On a site I'm working on, if you enter the url, plus 1 directory, the htaccess adds a trailing slash.
So, this: http://www.mysite.com/shirts
Becomes this: http://www.mysite.com/shirts/
The htaccess that runs the site is quite long and complex, so it's not easy to find or test which rule is causing the rewrite. I was able to track down the issue to this line of code (I think):
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Does this rule match the behavior I'm describing above? It seems to be the cause, but it doesn't make logical sense to me. I don't unsderstand where the trailing slash is coming from.
Can someone shed some light on this for me? Thanks in advance.
Edit: MORE:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
By default apache will add the ending /, you will have to use:
DirectorySlash Off
To disable that behavior which is caused by mod_dir, you can read more about it here.
However if you're trying to remove the / to fix images not showing. That is not the right way to do it, you should instead use the HTML base tag, for example:
<BASE href="http://www.yourdomain.com/">
Read more here about it.
Your current rule as you have updated on your question:
RewriteCond %{HTTP_HOST} ^mysite\.com$
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
Means:
if domain on the URL is only mysite.com
redirect current URL to domain with www.
So an example of it would be, if you access:
http://domain.com/blog/some_blog_article
It will redirect the user to:
http://www.domain.com/blog/some_blog_article
Note how it retains everything and only add the www. to the domain.
If you really want to redirect it regardless here is one way to do it:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule (.*) http://www.mysite.com/$1 [R=301,L]
# check if it is a directory
RewriteCond %{REQUEST_FILENAME} -d
# check if the ending `/` is missing and redirect with slash
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
# if file or directory does not exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# and we still want to append the `/` at the end
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]

301 Redirect - variable in the old url

I have several urls on a Joomla site which have been indexed and I need to 301 redirect them into some new pages. The old URL is formed like this:
http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=20
I want it to go to:
http://www.mydomain.com/en/family-members/family-disease
I tried using:
RewriteCond %{QUERY_STRING} ^start=(.*)$
RewriteRule ^/en/wfmenuconfig/family/family-disease/177-category-english$ http://www.www.mydoamin.com/en/family-members/family-disease%1 [R=301,L]
I've tried several answers on here but nothing seems to be working.
htaccess 301 redirect dynamic url
and
301 Redirecting URLs based on GET variables in .htaccess
Any ideas what I should try next? (I've tried a normal redirect 301)
You've almost got it. You need to remove the leading slash from your rule's pattern because it's removed from the URI when applying rules from an htaccess file:
RewriteCond %{QUERY_STRING} ^start=(.*)$
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english$ /en/family-members/family-disease%1? [R=301,L]
You also don't need the http://www.www.mydoamin.com bit (2 sets of www). At the end of your target, you have family-disease%1, which means if start=20 then the end of your URL will look like: family-disease20. Is that right?
The new URL doesn't have the query string in it, so it is just stripping of the last URL path part. If you want it hardcoded
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english$ /en/family-members/family-disease? [R,L]
or a little bit more flexible
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/family/family-disease/.+$ /en/family-members/family-disease? [R,L]
or if you just want to keep two levels after en/wfmenuconfig
RewriteCond %{QUERY_STRING} ^start=
RewriteRule ^en/wfmenuconfig/(.+?/.+?)/ /en/$1? [R,L]
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.
If you just want to redirect http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$var into http://www.mydomain.com/en/family-members/family-disease, then you must try these directives:
# once per .htaccess file
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english /en/family-members/family-disease [R=301,L]
But if that's not what you want, but to redirect http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$var into http://www.mydomain.com/en/family-members/family-disease$var then you could check this one:
# once per .htaccess file
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^en/wfmenuconfig/family/family-disease/177-category-english /en/family-members/family-disease%1 [R=301,L]
Now, give this one a little more try if it will work. If it's not, then find any suspicious why this code is not working:
Options +FollowSymlinks
RewriteEngine on
RewriteBase /en/
RewriteCond %{QUERY_STRING} start=([0-9]*)
RewriteRule ^wfmenuconfig/family/family-disease/177-category-english /family-members/family-disease [R]
And go to http://www.mydomain.com/en/wfmenuconfig/family/family-disease/177-category-english?start=$AnyNumber if it's redirecting into http://www.mydomain.com/en/family-members/family-disease just make sure that your web server have mod_rewrite.
I just wanted to throw this out there, I was also having trouble getting the RewriteRule to work. I have a client that upgraded to a WordPress powered site from .asp pages. What I had to do to get this to work is insert the RewriteCond and RewriteRule in the htaccess file BEFORE the "# BEGIN WordPress" section. Now it works just as it should.
This is posted way late, but hopefully it helps someone else out there running into the same issue.
Doesn't Work:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
RewriteCond %{QUERY_STRING} ^var=somestring$ [NC]
RewriteRule ^oldpage\.asp$ http://www.domain.com/newpage? [R=301,L]
Does Work:
RewriteCond %{QUERY_STRING} ^var=somestring$ [NC]
RewriteRule ^oldpage\.asp$ http://www.domain.com/newpage? [R=301,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Order of operations must be important =)

.htaccess, forcing a slash and www

Can someone please help me to force my website to redirect to using www. and ALWAYS add a slash at the end of any page? My htaccess file currently looks like this:
RewriteEngine on
RewriteRule blog/date/([^/]+)/?$ index.php?page=viewblog&date=$1
RewriteRule blog/([^/]+)/?$ index.php?page=viewblog&category=$1
RewriteRule blog/([^/]+)/([^/]+)/?$ index.php?page=viewblog&category=$1&title=$2
RewriteRule ^([^/\.]+)/?$ index.php?page=$1 [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([a-zA-Z0-9]+)
Many thanks in advance :)
This will work for any domain:
DirectorySlash on
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteRule .* http://www.%{HTTP_HOST}%{REQUEST_URI} [L]
This will add the slash when necessary. (%{REQUEST_URI} will be / with a request for root, or /whatever if you request domain.com/whatever.) It also won't put in two slashes (//) for the main domain as the other solution does. The DirectorySlash directive ensures the slash is added where appropriate even if the www is already present.
I do not know how to add the trailing slash, but adding www in front of URLs are quite simple.
Here's what im using to add the www before an url:
RewriteEngine on
Options FollowSymlinks
rewritecond %{http_host} ^yourdomain.com [nc]
rewriterule ^(.*)$ http://www.yourdomain.com/$1 [r=301,nc]
Googled for the trailing slash-thingy and found this article: http://www.mydigitallife.info/2007/03/19/add-trailing-slash-to-the-end-of-the-url-with-htaccess-rewrite-rules/
Hope this helps :-)

Resources