仅当存在查询字符串时,才会对图像文件请求执行RewriteRule

时间:2011-09-01 20:49:43

标签: regex apache .htaccess mod-rewrite

凭借我有限的正则表达式和mod_rewrite能力,我正在尝试重写某些图像请求,以便我可以使用php脚本更改输出。这就是我所拥有的:

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              ]

这确实有效,但是它太贪婪了并且不需要查询字符串,这很重要 - 否则所有图像请求都会被重写。我尝试在规则中放置??(.*),我会收到内部服务器错误,或者似乎无法解决问题(很可能是因为我没有正确执行) 。我也在条件结束时尝试了%{QUERY_STRING},但这似乎并没有影响任何事情。

这就是我想要发生的事情:

  • public/uploads/ ...
  • 的任何请求
  • 跟随图像的任何路径(文件扩展名不区分大小写)...
  • 后跟查询字符串......
  • ...应使用原始查询字符串重写为public/images.php,并添加一个aditional参数:src,其中包含图像的实际路径(重写的部分)。
  • 额外“会很好”,但不是必需的:如果查询字符串包含一组参数中的至少一个项目,则将规则限制为仅重写URL。例如,仅当存在width=height=contrast=参数之一时。如果这会让事情变得臃肿或复杂,我并不担心。

例如,请求:

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

应由以下人员提供:

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

.htaccess文件位于我的根目录以及publicuploads目录中。

我想避免使用绝对网址,因为我希望它可以移植而无需编辑。我已经做了大量的谷歌搜索和阅读相关的SO帖子,仍然无法弄清楚这一点。如何修改此规则以执行我想要的操作,或者是否有更好的方法可以完全写入此内容?

修改:只是想注意这条规则以前对我有用:

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

...但仅适用于像uploads/my_folder/image.jpg/280这样的请求 - 我使用280作为宽度,但现在我想接受多个参数的组合,没有特定的顺序:

1 个答案:

答案 0 :(得分:2)

两种方法:

1。添加条件只在查询字符串不为空时重写(可以是任何内容):

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。添加条件仅在查询字符串不为空且至少存在其中一个参数时重写(但值可以为空):

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]

我还没有真正测试过#2 ..但应该可以正常工作(从完全正常工作的代码中复制)。


备注:

您可以将^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$替换为^((?:public|uploads)/(?:[A-Za-z0-9/_-]+)\.(?:jpe?g|gif|png))$ ..然后代替src=$1/$2.$3仅使用src=$1

或者 - 将^(public|uploads)/([A-Za-z0-9/_-]+)\.(jpe?g|gif|png)$替换为^(?:public|uploads)/[A-Za-z0-9/_-]+\.(?:jpe?g|gif|png)$,然后使用src=${REQUEST_URI} - src=参数将以前导斜杠开头的唯一区别。