I want to redirect:
https://www.example.com/?p2
to https://www.example.com/
https://www.example.com/?p1=v1&p2&p3=v3
to https://www.example.com/?p1=v1&p3=v3
https://www.example.com/page.php?p4=v4&p2
to https://www.example.com/page.php?p4=v4
You can assume that the query string missing the value is always p2
, if that makes it easier to answer the question.
But the p2
query string will not always be missing the value, and I wouldn't want it removed in those cases.
.htaccess
You could do this in .htaccess
with a bunch of re-writes in a bunch of different ways...
Example 1:
RewriteCond %{QUERY_STRING} ^p2$
RewriteRule . / [QSD,L]
RewriteCond %{QUERY_STRING} ^(.+)&p2$
RewriteRule . /?%1 [L]
RewriteCond %{QUERY_STRING} ^p2&(.+)$
RewriteRule . /?%1 [L]
RewriteCond %{QUERY_STRING} ^(.+)&p2(&.+)$
RewriteRule . /?%1%2 [L]
Example 2:
RewriteCond %{QUERY_STRING} (^|.*&)p2(&.*|$)
RewriteRule . /?%1%2 [L]
// This doesn't give particularly clean query strings (not that they need to
// be for the server to understand it).
// e.g.
// ?p1=v1&p2&p3=v3 -> ?p1=v1&&p3=v3
Example 3:
RewriteCond %{QUERY_STRING} (^|.*&)p2(?:&(.*)|$)
RewriteRule . /test.php?%1%2 [L]
// ?p2&p3=v3 -> ?p3=v3
// ?p1=v1&p2 -> ?p1=v1
// ?p1=v1&p2&p3=v3 -> ?p1=v1&p3=v3
"This also makes use of a mod_rewrite "feature", where a trailing & on the resulting query string is automatically truncated/removed before being assigned to the Location HTTP response header." @MrWhite
As @MrWhite points out a trailing &
is truncated so having given this some more thought you could use the above as a one line condition to catch all possibilities (example input and output provided in commented lines //...
).
Whilst you can change the query string as shown above there's really no point messing about doing so when you can so easily deal with it in your script (eg PHP
):
if(empty($_GET["p2"])){
unset($_GET["p2"]);
}
Which you have to do anyway to process the query string on your page?!
Additional note
The rules above silently remove the query string. If you want the user to know then you should redirect as per @MrWhite's answer setting the flag [R=30X]
with the appropriate HTTP response code:
Another way to do this in .htaccess
...
RewriteCond %{QUERY_STRING} ^&?p2(?:&|$)(.*) [OR]
RewriteCond %{QUERY_STRING} (.+)&p2(&.*|$)
RewriteRule ^ %{REQUEST_URI}?%1%2 [R=302,L]
This should go near the top of your .htaccess
file, before other rewrites.
This handles all query string variations of the p2
URL parameter (with no value) and results in a "clean" query string. The URL is "corrected" with an external redirect. (Test first with a 302 - temporary - redirect before changing to 301 - permanent - if that is the intention, to avoid potential caching issues.)
Only one of the two OR'd conditions will match. The first condition handles the situation when p2
appears at the start of the query string. The second condition handles the situation when p2
appears later or at the end of the query string. This is so we don't get a mismatched or double &
(URL param delimiter) in the resulting substitution .
The %1
and %2
backreferences contain the first and second captured groups from the last matched CondPattern (whichever one that is). Basically the string(s) before and after the p2
parameter.
This also makes use of a mod_rewrite "feature", where a trailing &
on the resulting query string is automatically truncated/removed before being assigned to the Location
HTTP response header.
However, as has already been mentioned, depending on how prevalent this "erroneous" p2
URL is and where it appears then it may be preferable to simply "ignore" it and ensure you've set the appropriate rel="canonical"
element in your HTML.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.