问题
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/
oruploads/
... - 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=
orcontrast=
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