Apache mod_rewrite 让我抓狂

发布于 2024-08-28 03:14:52 字数 3099 浏览 3 评论 0原文

场景

我有一个在多个站点之间共享的虚拟主机,目录布局如下所示:

siteA/
    - css/
    - js/
    - index.php
siteB/
    - css/
    - js/
    - index.php
siteC/
    .
    .
    .

DocumentRoot 位于顶层,因此,要访问 siteA,请键入 http://webhost/siteA 在浏览器中,要访问 siteB,请输入 http:// /webhost/siteB, 等等。

现在我必须部署自己的网站,该网站的设计考虑了 3 个 VirtualHosts,因此我的结构如下所示:

siteD/
    - sites/sitename.com/
        - log/
        - htdocs/
            - index.php
    - sites/static.sitename.com
        - log/
        - htdocs/
            - css
            - js
    - sites/admin.sitename.com
        - log/
        - htdocs/
            - index.php

如您所见,问题是我的 index.php 文件不在顶级目录中,这与已经存在的目录不同。虚拟主机上的现有网站。 每个 VirtualHost 应该指向相应的 htdocs/ 文件夹:

http://siteD.com -> siteD/sites/sitename.com/htdocs
http://static.siteD.com -> siteD/sites/static.sitename.com/htdocs
http://admin.siteD.com -> siteD/sites/admin.sitename.com/htdocs

问题是

我不能在此主机上拥有 VirtualHosts,因此我必须以某种方式模拟它,可能使用 mod_rewrite。

这个想法

在网站上的所有链接中都有一些预定义的部分,我可以识别这些部分,并使用 mod_rewrite 相应地路由到正确的文件。

示例:

http://webhost/siteD/static/js/something.js -> siteD/sites/static.sitename.com/htdocs/js/something.js
http://webhost/siteD/static/css/something.css -> siteD/sites/static.sitename.com/htdocs/css/something.css
http://webhost/siteD/admin/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/admin/sub/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/something -> siteD/sites/sitename.com/htdocs/index.php
http://webhost/siteD/sub/something -> siteD/sites/sitename.com/htdocs/index.php

任何以 http://url/sitename/admin/(.*) 开头的内容都将被重写,指向 siteD/sites/admin.sitename.com/htdocs/index.php

http:// 开头的任何内容url/sitename/static/(.*) 将被重写,指向 siteD/sites/static.sitename.com/htdocs/$1

任何以 http://url/sitename/(.*) AND 上面没有匹配项,将被重写以指向 siteD/ site/sitename.com/htdocs/index.php

解决方案

这是我提出的 .htaccess 文件:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} ^/siteD/static/(.*)$ [NC]
RewriteRule ^siteD/static/(.*)$ siteD/sites/static/htdocs/$1 [L]

RewriteCond %{REQUEST_URI} ^/siteD/admin/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/admin/htdocs/index.php [L,QSA]

到目前为止,一切都很好。一切正常。现在添加最后一条规则:

RewriteCond %{REQUEST_URI} ^/siteD/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/public/htdocs/index.php [L,QSA]

它已被破坏。最后一条规则捕获所有内容,甚至包括那些包含 static/ 或 admin/ 的规则。 为什么?在前两种情况下, [L] 标志不应该停止重写过程吗?为什么要评估第三种情况?

有更好的方法来解决这个问题吗?我不坚持使用 rewritemod,只要不需要访问服务器级配置,一切都可以。

我无权访问 RewriteLog 或类似的东西。 请帮忙:(

The scenario

I have a webhost that is shared among multiple sites, the directory layout looks like this:

siteA/
    - css/
    - js/
    - index.php
siteB/
    - css/
    - js/
    - index.php
siteC/
    .
    .
    .

The DocumentRoot is at the top level, so, to access siteA, you type http://webhost/siteA in your browser, to access siteB, you type http://webhost/siteB,
and so on.

Now I have to deploy my own site, which was designed with having 3 VirtualHosts in mind, so my structure looks like this:

siteD/
    - sites/sitename.com/
        - log/
        - htdocs/
            - index.php
    - sites/static.sitename.com
        - log/
        - htdocs/
            - css
            - js
    - sites/admin.sitename.com
        - log/
        - htdocs/
            - index.php

As you see, the problem is that my index.php files are not at the top level directory, unlike the already existing sites on the webhost.
Each VirtualHost should point to the corresponding htdocs/ folder:

http://siteD.com -> siteD/sites/sitename.com/htdocs
http://static.siteD.com -> siteD/sites/static.sitename.com/htdocs
http://admin.siteD.com -> siteD/sites/admin.sitename.com/htdocs

The problem

I cannot have VirtualHosts on this host, so I have to emulate it somehow, possibly with mod_rewrite.

The idea

Have some predefined parts in all of the links on the site, that I can identify, and route accordingly to the correct file, with mod_rewrite.

Examples:

http://webhost/siteD/static/js/something.js -> siteD/sites/static.sitename.com/htdocs/js/something.js
http://webhost/siteD/static/css/something.css -> siteD/sites/static.sitename.com/htdocs/css/something.css
http://webhost/siteD/admin/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/admin/sub/something -> siteD/sites/admin.sitename.com/htdocs/index.php
http://webhost/siteD/something -> siteD/sites/sitename.com/htdocs/index.php
http://webhost/siteD/sub/something -> siteD/sites/sitename.com/htdocs/index.php

Anything that starts with http://url/sitename/admin/(.*) will get rewritten, to point to siteD/sites/admin.sitename.com/htdocs/index.php

Anything that starts with http://url/sitename/static/(.*) will get rewritten, to point to siteD/sites/static.sitename.com/htdocs/$1

Anything that starts with http://url/sitename/(.*) AND did not have a match already from above, will get rewritten to point to siteD/sites/sitename.com/htdocs/index.php

The solution

Here is the .htaccess file that I've come up with:

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} ^/siteD/static/(.*)$ [NC]
RewriteRule ^siteD/static/(.*)$ siteD/sites/static/htdocs/$1 [L]

RewriteCond %{REQUEST_URI} ^/siteD/admin/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/admin/htdocs/index.php [L,QSA]

So far, so good. It's all working. Now to add the last rule:

RewriteCond %{REQUEST_URI} ^/siteD/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/public/htdocs/index.php [L,QSA]

And it's broken. The last rule catches everything, even the ones that have static/ or admin/ in them.
Why? Shouldn't the [L] flag stop the rewriting process in the first two cases? Why is the third case evaluated?

Is there a better way of solving this? I'm not sticking to rewritemod, anything is fine as long as it does not need access to server-level config.

I don't have access to RewriteLog, or anything like that.
Please help :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明明#如月 2024-09-04 03:14:52

这很奇怪,但是您可以在最后一个模式中添加其他条件,即如果与前面的模式不匹配,则使用它:

RewriteCond %{REQUEST_URI} !^/siteD/static/(.*)$ [NC]
RewriteCond %{REQUEST_URI} !^/siteD/admin/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/public/htdocs/index.php [L,QSA]

That is strange, but you can add other conditions to the last pattern, i.e. use it if not matching the previous patterns:

RewriteCond %{REQUEST_URI} !^/siteD/static/(.*)$ [NC]
RewriteCond %{REQUEST_URI} !^/siteD/admin/(.*)$ [NC]
RewriteRule ^siteD/(.*)$ siteD/sites/public/htdocs/index.php [L,QSA]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文