Apache Rewrite:基于HTTP主机的图像目录

时间:2012-02-05 18:37:48

标签: apache .htaccess mod-rewrite

我的软件支持多个域名,所有域名都指向服务器上的同一目录(当然每个目录都有不同的数据库)。所以这些领域......

www.example1.com
www.example2.com
www.example3.com

......都指向......

/public_html/

在图片目录中......

/public_html/images/

我的目录与每个网站的主机名完全匹配:

/public_html/images/www.example1.com/
/public_html/images/www.example2.com/
/public_html/images/www.example3.com/

我正在尝试让Apache重写请求,这样如果您直接查看图像并查看地址栏,您只能看到一次主机名。

请求...

http://www.example1.com/images/book.png

...由Apache在...

提取
/public_html/images/www.example1.com/book.png

我尝试过并且在不同情况下取得成功的其中一件事情如下:虽然它在这种情况下不起作用:

RewriteRule ^[^/]*/images(.+) images/%{HTTP_HOST}/$1

3 个答案:

答案 0 :(得分:2)

尝试将以下内容添加到您网站根目录中的.htaccess文件中(public_html)

RewriteEngine on
RewriteBase / 

#prevent looping from internal redirects
RewriteCond %{ENV:REDIRECT_STATUS} !200
#only rewrite gif, jpg or png
RewriteRule ^(images)(/.+\.(gif|jpg|png))$ $1/%{HTTP_HOST}$2 [L,NC] 

你的规则

RewriteRule ^[^/]*/images(.+) images/%{HTTP_HOST}/$1

无效,因为您在/之前有一个前导images。在.htaccess中,前导/被删除,因此规则永远不会匹配。

答案 1 :(得分:1)

这是我为我的高性能框架所做的一件事(参见我的简历)。

我给你一个高级的RewriteRule,我很确定你有足够的材料来完成:

创建静态域:

static.example1.com
static.example2.com
static.example3.com

所有图片都在哪里。

从现在开始,不再:

www.example1.com/images/www.example1.com/picture.jpg
www.example2.com/images/www.example2.com/picture.jpg
www.example3.com/images/www.example3.com/picture.jpg

static.example1.com/picture.jpg
static.example2.com/picture.jpg
static.example3.com/picture.jpg

好的网址呃? 现在创建一个包含所有静态文件的vhost:

<VirtualHost *>
    ServerName static.example1.com
    ServerAlias static.example2.com static.example3.com
</VirtualHost>

将文档根目录设置为没有vhost名称的基础,因此在您的情况下:

DocumentRoot "/public_html/images"

并添加此RewriteRule

RewriteCond %{HTTP_HOST} ^static\.([a-zA-Z0-9\-]+)\.com$
# Change the path, and add the request:
RewriteRule  (.*) %{DOCUMENT_ROOT}/static.%1.com$1 [QSA,L]
总而言之:

<VirtualHost *>
    ServerName static.example1.com
    ServerAlias static.example2.com static.example3.com
    RewriteCond %{HTTP_HOST} ^static\.([a-zA-Z0-9\-]+)\.com$
    # Change the path, and add the request:
    RewriteRule  (.*) %{DOCUMENT_ROOT}/static.%1.com$1 [QSA,L]
</VirtualHost>

好的,这并不能完全回答你的问题,所以这里的答案很简短,但我不喜欢它,因为它无助于你做一件非常好的工作:

    RewriteCond %{HTTP_HOST} ^www\.(example1|example2|example3)\.com$
    # Change the path:
    RewriteRule (.*)(\.(css|js|txt|htc|pdf|jpg|jpeg|gif|png|ico))$ %{DOCUMENT_ROOT}/www.%1.com$1$2 [QSA,L]

如果这还不够:

两个提示:

如果您在托管环境中(=如果它是您自己的服务器可以修改虚拟主机,不仅仅是.htaccess文件),尝试使用RewriteLog指令:它可以帮助您找出这些问题:

# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On

我最喜欢检查regexp的工具:

http://www.quanetic.com/Regex(别忘了选择ereg(POSIX)而不是preg(PCRE)!)

答案 2 :(得分:1)

约翰,

我刚刚针对您面临的一些挑战发布separate Q。我欢迎你的评论,但回到你的挑战:一个技巧,你可以使用环境变量来存储你的(最好是经过验证的)主机,例如:

RewriteCond %{HTTP_HOST} ^www\.(host1|host2|host3\.com
RewriteRule ^ -  [E=HOST:%1]

您可能还想添加[S]标志以在规则中实现if / then / else逻辑。您还可以将以下规则或条件字符串(而非正则表达式)中的HOST变量用作%{ENV:HOST}。

您还需要仔细查看完整的phpinfo()报告,以了解托管服务是使用mod_php还是mod_suPHP,...接口和主机它支持DNS多宿主。例如,我的供应商在检查文件空间时设置%{ENV:DOCUMENT_ROOT_REAL},而不是%{DOCUMENT_ROOT}。

您在DOCROOT /的所有URI“到达”的格式均为http://www.exampleX.com/images/book.png,因此,如果您的.htaccess位置是您的DOCROOT,那么您的基数为/。所以假设上面的ENV设置,这些应该可以工作

RewriteBase /

RewriteCond %{HTTP_HOST} ^www\.(host1|host2|host3)\.com
RewriteRule ^ -  [E=HOST:%1]

RewriteCond %{ENV:HOST}==%{REQUEST_URI}  !^(.*?)==/image/\1
RewriteRule ^image/(.*) image/%{ENV:HOST}/$1     [L,NS]  

cond是一个停止重写规则循环的方法。

广义版

以上解决方案一个已经广泛使用的解决方案。只需将RewriteCond正则表达式替换为与您自己的命名约定匹配的任何模式,并且我同意如果它是(。*),那么您也可以删除第一条规则并将%{ENV:HOST}替换为%{HTTP_HOST}.你需要RewriteCond防护来防止循环导致500。