我正在创建一个多租户项目,其地址结构如下
https://example.com/TENANTNAME/file.php
https://example.com/TENANTNAME/api/file.php
https://example.com/TENANTNAME/assets/js/main.js
并将其重写到单个子文件夹,例如 /BASE/ - 这个想法是我可以拥有一组文件,然后检查 URL 以找出其余部分。
谢谢你
我确实通过以下方式使其工作到了一定程度,但进一步的子文件夹(从子域编辑)未正确重定向,因此主index.php很好,但资产文件夹中的任何内容都给出了服务器错误
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/BASE/(.*)/
RewriteRule ^(.*)/(.*)$ /BASE/$2 [L]
作为示例,我期望进行以下内部重写
https://example.com/TENANTNAME/index.php
到
https://example.com/BASE/index.php
https://example.com/TENANTNAME/assets/js/main.js
到
https://example.com/BASE/assets/js/main.js
index.php 示例确实符合我的尝试,但是带有更多子文件夹的资产示例则不然
我的第一个问题是“磁盘上是否存在通配符文件夹?”
如果是,那么前两个重写条件可能会 当请求与现有文件匹配时停止执行重写规则 或目录。
所以我认为你可以删除这些条件,因为你可能不需要 他们。
下一个重写条件,测试它不是
/BASE/
根
目录,应该足够了。但可以稍微优化一下
更换
RewriteCond %{REQUEST_URI} !^/BASE/(.*)/
由
RewriteCond %{REQUEST_URI} !^/BASE/
我们不需要捕获第二个斜杠后面的内容。它实际上 创建一个名为
%1
的变量,可以在重写规则中使用
目标网址。但无论如何,我们还有一些其他捕获组
在重写条件本身。
它们可能是正则表达式中的贪婪小问题 重写规则。
^(.*)/
可以捕获许多字符,导致
捕获其他一些斜线。所以有两种解决方案:
通过添加问号使其变得不贪婪:
^(.*?)/
*
替换为 +
因为我们想要匹配
至少一个字符。
代替点,使用“不是斜线”:
^([^/]+)/
另外,我认为您的 PHP 脚本可能想知道什么 是重写之前的原始 URL。您可以获得这些信息 通过读取
$_SERVER
数组,但为什么不将其转换为查询
无论如何,我们捕获的参数?这可以通过以下方式实现:
RewriteRule ^([^/]+)/(.*)$ /BASE/$2?original_root=$1 [L,QSA]
第一个捕获组是
$1
,可以添加到捕获组的末尾
URL,作为查询参数。顺便说一句,重写规则模式是
应用于不带查询字符串的路径(通常添加
返回目标 URL)。但在这里,当我创建一个新查询时
字符串,我必须启用 QSA
选项,该选项将附加
原始查询字符串 新创建的查询字符串。
(QSA = query string apend)。
这样,URL 如下:
/any-folder/something/script.php?id=6&op=view
应该变成:
/BASE/something/script.php?original_root=any-folder&id=6&op=view