Home > Back-end >  Rewrite encoded URLs with RewriteRules
Rewrite encoded URLs with RewriteRules

Time:02-21

I was rewritting "domain.com/lolmeter/platformValue/usernameValue" (platformValue and usernameValue are values requested by the user with text inputs) with the following rewrite rule:

RewriteRule ^lolmeter/([a-zA-Z0-9]*)/([a-zA-Z0-9]*)$ /lolmeter.html?platform=$1&username=$2 [L]
    
button.href = lolmeter/platformValue/usernameValue

I noticed that when the user inputs a whitespace or another non alphanumeric value, it is encoded with "%" symbols automatically, so I tried to rewrite the rule to accept them, like:

RewriteRule ^lolmeter/(([a-zA-Z0-9]|%)*)/(([a-zA-Z0-9]|%)*)$ /lolmeter.html?platform=$1&username=$2 [L]

But it doesn't work, I assume because of the parentheses. Which symbol should I use then for an inner "|" ?

P.S: Is there a more popular or modern way for changing URLs?

CodePudding user response:

RewriteRule ^lolmeter/(([a-zA-Z0-9]|%)*)/(([a-zA-Z0-9]|%)*)$ /lolmeter.html?platform=$1&username=$2 [L]

The RewriteRule pattern matches against the %-decoded URL-path. So, if an encoded space (ie. ) is present in the URL-path of the request then the rule matches against a literal space, not .

You can use the \s shorthand character class inside the character class in your regex to match any whitespace character.

For example:

RewriteRule ^lolmeter/([a-zA-Z0-9\s] )/([a-zA-Z0-9\s]*)$ /lolmeter.html?platform=$1&username=$2 [L]

Note that I made the quantifier on the second/middle path segment instead of * since I assume the middle path segment is not optional. Note that multiple contiguous slashes in the URL-path are also reduced before the regex is matched so if the middle path segment was omitted then the passed username would be seen as the platform, which I'm sure is not the intention.

Note also that in the above the space is not re-encoded in the resulting rewrite. Use the B flag to re-encode the space as a in the query string. (If you specifically needed the space to be re-encoded as then use the BNP flag as well - requires Apache 2.4.26)

P.S: Is there a more popular or modern way for changing URLs?

Not sure exactly what you mean by this, but mod_rewrite on Apache is the URL rewriting module. Always has been and probably always will be.

However, you don't necessarily need to rewrite the request the way you have done, although you may still want to match the URL in a similar way (depending on what else you are doing). You could perhaps just rewrite the request to lolmeter.html and have your script parse the URL-path directly, rather than the query string.

Or, I suppose the "modern way" would be to rewrite everything to a "front-controller" - an entry script that parses the URL and "routes" the request appropriately. This avoids having to have a multitude of rewrites in .htaccess. Although this isn't anything "new", it has perhaps become more common. Many CMS/frameworks use this pattern.

  • Related