You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用.htaccess将通配符子目录重写到单一子目录

多租户项目的.htaccess重写规则修复方案

需求说明

需要搭建多租户项目,URL结构如下:

  • https://example.com/TENANTNAME/file.php
  • https://example.com/TENANTNAME/api/file.php
  • https://example.com/TENANTNAME/assets/js/main.js

要求将所有请求内部重写到单一子目录/BASE/,只维护一套核心文件,通过URL中的TENANTNAME识别租户。

原规则问题

尝试了以下.htaccess规则,仅根目录的index.php能正常工作,assets等深层子目录下的文件会触发服务器错误:

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

问题分析

原规则存在两个核心问题:

  1. ^(.*)/(.*)$的贪婪匹配会错误截断路径:当URL包含多层子目录时,第一个.*会匹配到TENANTNAME/assets/js这类长字符串,导致重写后路径丢失中间层级,变成/BASE/main.js而非预期的完整路径
  2. RewriteCond %{REQUEST_URI} !^/BASE/(.*)/的正则写法冗余且有误,末尾的斜杠会导致无法正确匹配/BASE/下的文件,反而干扰重写逻辑

修复后的规则

RewriteEngine On

# 排除BASE目录本身的请求,避免重写循环
RewriteRule ^BASE/ - [L]

# 匹配开头的租户名(不含斜杠),将后续完整路径重写到BASE目录
RewriteRule ^([^/]+)/(.*)$ /BASE/$2 [L]

规则解释

  1. RewriteRule ^BASE/ - [L]:直接放行/BASE/目录下的请求,防止出现重写循环
  2. ^([^/]+)/(.*)$:精准捕获第一个路径段作为租户名([^/]+确保只匹配不含斜杠的字符串),后续所有路径完整保留,重写到/BASE/目录的对应位置

修复后,无论请求是根目录文件还是深层子目录资源,都能正确映射到/BASE/下的对应文件。你可以通过解析原URL或读取$_SERVER['REQUEST_URI']来获取租户名TENANTNAME。

内容的提问来源于stack exchange,提问作者user3752011

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:13:18