RewriteRule for image file requests only if a query string is present

拜拜、爱过 提交于 2019-12-13 15:23:41

问题


With my limited regular expression and mod_rewrite abilities, I'm attempting to rewrite certain image requests so I can alter the output with a php script. Here's what I have:

RewriteRule ^(public|uploads)/([A-Za-z0-9/_-]+).(JPEG|JPG|GIF|PNG|jpeg|jpg|gif|png)$ public/images.php?%{QUERY_STRING}&src=$1/$2.$3 [L]
#            [       1      ] [       2       ] [                  3              ]

This does work, but it's too greedy and doesn't require the query string, which is important - otherwise all images requests would be rewritten. I tried putting a ? or ?(.*) in the rule, and I would either get an internal server error or it didn't seem to solve the problem (most likely because I didn't do it correctly). I also tried %{QUERY_STRING} at the end of the condition, but that didn't seem to affect anything.

Here's what I want to happen:

  • Any requests for public/ or uploads/...
  • Followed by any path to an image (file extension case insensitive)...
  • Followed by a query string...
  • ...should rewrite to public/images.php with the original query string, and add one aditional parameter: src, which contains the actual path to the image (the rewritten part).
  • Extra "would-be-nice", but not necessary: Restrict the rule to only rewrite the url if the query string contains at least one item from a set of parameters. For example, only if one of the width=, height= or contrast= params are present. If this makes things bloated or complicated, I'm not worried about it.

So for example, a request for:

uploads/images/my_folder/test.jpg?width=320&height=220

Should be served by:

public/images.php?width=320&height=220&src=public/images/my_folder/test.jpg

The .htaccess file is in my root directory, as well as the public and uploads directories.

I want to avoid absolute urls, because I want this to be portable without needing to edit. I've done a good deal of googling and reading related SO posts, and still can't figure this one out. How can I patch this rule to do what I want, or is there a better way to do write this altogether?

Edit: Just want to note that this rule worked for me previously:

RewriteRule ^(public|uploads)/([A-Za-z0-9/_-]+).(JPEG|JPG|GIF|PNG|jpeg|jpg|gif|png)/([0-9]+)$ public/images.php?width=$4&src=$1/$2.$3

...but only for requests like uploads/my_folder/image.jpg/280 - I used the 280 as the width, but now I want to accept combinations of multiple parameters in no particular order:


回答1:


Two approaches:

1. Add a condition to only rewrite when query string is not empty (can be anything):

RewriteCond %{QUERY_STRING} !^$
RewriteRule ^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$ public/images.php?src=$1/$2.$3 [NC,QSA,L]

2. Add a conditions to only rewrite when query string is not empty and has at least one of those parameters present (but the value can be empty):

RewriteCond %{QUERY_STRING} (^|&)width=([^&]*)(&|$) [OR]
RewriteCond %{QUERY_STRING} (^|&)height=([^&]*)(&|$) [OR]
RewriteCond %{QUERY_STRING} (^|&)contrast=([^&]*)(&|$)
RewriteRule ^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$ public/images.php?src=$1/$2.$3 [NC,QSA,L]

I have not really tested #2 .. but should work fine (copied from fully working code).


NOTES:

You can replace ^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$ by ^((?:public|uploads)/(?:[A-Za-z0-9/_-]+)\.(?:jpe?g|gif|png))$ .. and then instead of src=$1/$2.$3 use just src=$1

Alternatively -- replace ^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$ by ^(?:public|uploads)/[A-Za-z0-9/_-]+\.(?:jpe?g|gif|png)$ and then use src=${REQUEST_URI} -- the only difference that src= parameter will start with leading slash.



来源:https://stackoverflow.com/questions/7276348/rewriterule-for-image-file-requests-only-if-a-query-string-is-present

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!