RewriteCond to match query string parameters in any order

后端 未结 3 636
天涯浪人
天涯浪人 2020-12-02 19:35

I have a URL which may contain three parameters:

  1. ?category=computers
  2. &subcategory=laptops
  3. &product=dell-inspiron-15

I

3条回答
  •  时光取名叫无心
    2020-12-02 20:02

    You can achieve this with multiple steps, by detecting one parameter and then forwarding to the next step and then redirecting to the final destination

    RewriteEngine On
    
    RewriteCond %{QUERY_STRING} ^category=([^&]+) [NC,OR]
    RewriteCond %{QUERY_STRING} &category=([^&]+) [NC]
    RewriteRule ^index\.php$ $0/%1
    
    RewriteCond %{QUERY_STRING} ^subcategory=([^&]+) [NC,OR]
    RewriteCond %{QUERY_STRING} &subcategory=([^&]+) [NC]
    RewriteRule ^index\.php/[^/]+$ $0/%1
    
    RewriteCond %{QUERY_STRING} ^product=([^&]+) [NC,OR]
    RewriteCond %{QUERY_STRING} &product=([^&]+) [NC]
    RewriteRule ^index\.php/([^/]+/[^/]+)$ http://store.example.com/$1/%1/? [R,L]
    

    To avoid the OR and double condition, you can use

    RewriteCond %{QUERY_STRING} (?:^|&)category=([^&]+) [NC]
    

    as @TrueBlue suggested.

    Another approach is to prefix the TestString QUERY_STRING with an ampersand &, and check always

    RewriteCond &%{QUERY_STRING} &category=([^&]+) [NC]
    

    This technique (prefixing the TestString) can also be used to carry forward already found parameters to the next RewriteCond. This lets us simplify the three rules to just one

    RewriteCond &%{QUERY_STRING} &category=([^&]+) [NC]
    RewriteCond %1!&%{QUERY_STRING} (.+)!.*&subcategory=([^&]+) [NC]
    RewriteCond %1/%2!&%{QUERY_STRING} (.+)!.*&product=([^&]+) [NC]
    RewriteRule ^index\.php$ http://store.example.com/%1/%2/? [R,L]
    

    The ! is only used to separate the already found and reordered parameters from the QUERY_STRING.

提交回复
热议问题