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

如何用.htaccess将所有URI请求(含文件夹)重定向到index.php?

问题:.htaccess配置将所有URI(含文件夹)重定向到index.php失败

我的根目录结构如下:

  • app
  • admin
  • public
  • index.php
  • .htaccess

我需要实现所有URI请求(包括与现有文件夹同名的请求)都重定向到index.php,当前情况:

  • www.example.com/anything → 正常,已重定向到index.php,无HTTP错误
  • www.example.com/admin → 失败,返回HTTP 403 Forbidden(无权访问此资源)

其他请求均正常,只有访问与现有文件夹同名的URI时会出现禁止错误,请问如何修改配置,让所有请求都交由index.php处理?

当前的.htaccess配置:

<IfModule mod_rewrite.c> 
    Options -MultiViews -Indexes +FollowSymLinks 

    # 开启重写引擎
    RewriteEngine On
    RewriteBase /

    # HTTP重定向到HTTPS
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

    # 将请求重定向到index.php
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php/$1 [NC,L,QSA] 

    # 拦截恶意查询字符串
    RewriteCond %{QUERY_STRING} proc/self/environ [OR]
    RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
    RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
    RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
    RewriteCond %{QUERY_STRING} GLOBALS(=|[|\%[0-9A-Z]{0,2}) [OR]
    RewriteCond %{QUERY_STRING} _REQUEST(=|[|\%[0-9A-Z]{0,2})

    # 将拦截到的请求返回403并指向index.php
    RewriteRule ^(.*)$ index.php [F,L]
</IfModule>

更新:
按照建议移除了Options中的-Indexes以及目录条件RewriteCond %{REQUEST_FILENAME} !-d,但访问www.example.com/admin时出现ERR_TOO_MANY_REDIRECTS(重定向次数过多)错误。

修改后的.htaccess配置:

Options -MultiViews +FollowSymLinks 

# 将请求重定向到index.php 
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteRule ^(.*)$ index.php/$1 [NC,L,QSA] 

解决方案

问题根源分析

  1. 原配置中RewriteCond %{REQUEST_FILENAME} !-d规则会跳过对现有目录的重写,加上-Indexes禁止了目录索引,导致访问/admin时Apache找不到目录入口文件,直接返回403。
  2. 移除!-d后出现循环,是因为重写后的index.php/admin会被Apache解析为index.php加路径信息,而规则没有排除index.php本身,导致反复匹配触发循环。

正确配置

<IfModule mod_rewrite.c> 
    Options -MultiViews +FollowSymLinks 

    # 开启重写引擎
    RewriteEngine On
    RewriteBase /

    # HTTP重定向到HTTPS(无需可删除)
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

    # 直接放行index.php本身,避免循环
    RewriteRule ^index.php$ - [L]

    # 重定向所有请求(含目录)到index.php,真实存在的文件直接访问(无需可删除!-f条件)
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteRule ^(.*)$ index.php/$1 [NC,L,QSA] 

    # 拦截恶意查询字符串
    RewriteCond %{QUERY_STRING} proc/self/environ [OR]
    RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
    RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
    RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
    RewriteCond %{QUERY_STRING} GLOBALS(=|[|\%[0-9A-Z]{0,2}) [OR]
    RewriteCond %{QUERY_STRING} _REQUEST(=|[|\%[0-9A-Z]{0,2})

    # 返回403并指向index.php
    RewriteRule ^(.*)$ index.php [F,L]
</IfModule>

关键修改说明

  • RewriteRule ^index.php$ - [L]:直接放行index.php请求,彻底避免重写循环。
  • 保留RewriteCond %{REQUEST_FILENAME} !-f:如果请求是真实存在的静态文件(如图片、CSS),直接访问不重写;若需要连静态文件也交由index.php处理,可删除此条件。
  • 移除-Indexes后,即使保留该选项,因目录请求已被重写,也不会再触发403错误。

内容的提问来源于stack exchange,提问作者Antonio Da Silva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:45:03