如何通过 .htaccess 正确重写静态资源路径并避免重定向循环

如何通过 .htaccess 正确重写静态资源路径并避免重定向循环

本文详解如何配置 apache 的 `.htaccess` 文件,使 `/css/main.css` 等静态资源请求自动映射到 `public/css/main.css`,同时确保 mvc 路由不冲突、无重定向循环。

在基于 MVC 架构的 PHP 应用中,将 Web 可访问文件(如 CSS、JS、图片)统一置于 public/ 目录是常见且安全的做法。但若希望前端 HTML 中直接使用 而非 ,就必须借助 .htaccess 实现「透明路径重写」——即浏览器请求 /css/main.css 时,服务器内部将其指向 public/css/main.css,而 URL 地址栏保持不变。

关键挑战在于:避免重写规则间的冲突与无限重定向循环。原始配置中 RedirectMatch 与后续 RewriteRule 未做前置拦截,导致对已重写为 public/xxx 的请求再次匹配、反复重写,最终触发 500 错误或浏览器重定向失败。

以下是经过生产验证的、结构清晰且具备防御性的 .htaccess 配置(适配子目录部署场景,如 /BU/cs-602/developer-story/):


    RewriteEngine On
    RewriteBase /BU/cs-602/developer-story/

    # 1. 首页请求:/ 或 /index.* → public/index.php(终止)
    RewriteRule ^(//||.*index/..*)$ public/index.php [L,QSA]

    # 2. 安全短路:若请求路径已含 "public/",直接放行(防止循环)
    RewriteRule ^(.*public//.*)$ $1 [L,QSA]

    # 3. 静态资源识别:匹配非 PHP/HTML/HTM 的扩展名(如 .css, .js, .png)
    RewriteCond %{REQUEST_URI} /.(?!php|htm|html)[a-zA-Z0-9]+$ [NC]
    # → 重写为 public/ + 原路径,并终止(L)
    RewriteRule ^(.*)$ public/$1 [L,QSA]

    # 4. MVC 路由兜底:仅当请求路径不是真实文件/目录/符号链接时,交由 index.php 处理
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule ^([/w/d/s/-/_///%]*)$ public/index.php?p=$1 [L,QSA]

核心设计逻辑说明:

Viggle AI

Viggle AI

Viggle AI是一个AI驱动的3D动画生成平台,可以帮助用户创建可控角色的3D动画视频。

下载

  • 顺序即优先级:Apache 按从上到下执行规则,[L](Last)标志确保匹配后立即终止当前轮次,防止后续规则干扰;
  • 短路防御机制:第 2 条规则显式放行所有含 public/ 的路径,彻底阻断「public/css/main.css → 再次被识别为静态资源 → 重写为 public/public/css/main.css」的死循环;
  • 精准静态资源判定:使用 RewriteCond + 正则 /.(?!php|htm|html)[a-zA-Z0-9]+$ 安全排除脚本类文件,[NC] 保证大小写不敏感(.CSS 同样生效);
  • 子目录兼容性:RewriteBase 确保所有相对路径重写均基于实际部署路径(如 /BU/cs-602/developer-story/),无需硬编码完整 URL。

⚠️ 注意事项:

  • 确保 Apache 已启用 mod_rewrite 模块,并在虚拟主机配置中允许 .htaccess 覆盖(AllowOverride All);
  • 开发阶段务必开启 Apache 错误日志(LogLevel warn rewrite:trace3),可快速定位重写循环或正则匹配失败问题;
  • HTML 中资源引用保持简洁:如何通过 .htaccess 正确重写静态资源路径并避免重定向循环 即可,无需添加 public/ 前缀;
  • 若需支持更多静态类型(如 .woff2, .svg),可在 RewriteCond 正则中扩展:/.(?!php|htm|html|woff2|svg)[a-zA-Z0-9]+$。

该方案已在本地开发环境(XAMPP/MAMP)及 Linux 服务器实测通过,兼顾安全性、可维护性与 MVC 架构规范,是子目录部署型 PHP 应用的标准实践之一。

https://www.php.cn/faq/1973001.html

发表回复

Your email address will not be published. Required fields are marked *