RewriteRule: Querystring verwijderen in Apache < 2.4

Apache 2.4 voegt de [QSD] flag toe aan de RewriteRule directive. QSD staat voor Query String Discard en dient, zoals Apache stelt, to simplify common rewriting scenarios.

Het defaultgedrag van RewriteRule is om een eventuele querystring van de inkomende URL vast te plakken aan de uitgaande URL (mits de uitgaande URL zelf geen querystring bevat). Door toevoeging van de [QSD] flag wordt dit voorkomen.

When the requested URI contains a query string, and the target URI does not, the default behavior of RewriteRule is to copy that query string to the target URI. Using the [QSD] flag causes the query string to be discarded.
-- http://httpd.apache.org/docs/current/rewrite/flags.html#flag_qsd

Een handige toevoeging aan de toch al uitgebreide mogelijkheden die mod_rewrite biedt, bijvoorbeeld in het volgende, aan de praktijk ontleende voorbeeld waarin bij vernieuwing van een website de oude -querystring gebaseerde- paden zijn vervangen door friendly URLs:

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=8$
RewriteRule ^(.*)$ /over-ons/onze producten [L,R=301]

Deze code leidt in de praktijk tot een oneindige lus: omdat de RewriteCond is gebaseerd op de querystring en deze door RewriteRule aan de uitgaande URL weer wordt toegevoegd, zal mod_rewrite de URL steeds opnieuw blijven redirecten, totdat Apache of de browser het opgeeft. Toevoeging van de [QSD] flag zorgt dat bovenstaande redirect soepeltjes verloopt.

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=8$
RewriteRule ^(.*)$ /over-ons/onze producten [L,R=301,QSD]

QSD vóór Apache 2.4

Wie niet de laatste versie van de HTTPD server gebruikt zal het zonder deze flag moeten stellen, waarbij een geval als bovenstaand niet alleen voor een oneindige lus maar ook voor het nodige hersenbreken, om niet te zeggen slapeloze nachten kan zorgen. Want: hoe Apache duidelijk te maken dat deze rewrite na de eerste keer uitvoeren niet nogmaals moet worden uitgevoerd?

De oplossing is even onverwacht als eenvoudig: zoals hierboven gezegd plakt RewriteRule de querystring aan de uitgaande URL mits de uitgaande URL zelf geen querystring bevat!  Door achter de rewrite rule een ? (vraagteken) te plaatsen, beschouwt RewriteRule dat in de uitgaande URL een querystring aanwezig is en plakt aldus de oude querystring er niet achter, terwijl vervolgens dit losstaande vraagteken van de URL verwijderd wordt (kennelijk als zijnde overbodige rommel) zodat keurig een uitgaande URL overblijft zoals bedoeld. 

RewriteCond %{QUERY_STRING} ^main_page=index&cPath=8$
RewriteRule ^(.*)$ /over-ons/onze producten? [L,R=301]