简体   繁体   中英

htaccess: remove URL parameter from query string with missing value?

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.

Fix in .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 //... ).

Fix it in script

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:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM