伪静态需排除静态资源目录以避免404;apache用rewritecond !^/(static|uploads|themes)/等提前拦截,nginx用location ^~ /static/等优先匹配并alias,均须注意路径开头斜杠与权限配置。

伪静态规则默认会把所有请求都重写到 index.php,但你肯定不希望 public/static/、robots.txt 或上传目录(比如 uploads/)也被重写——否则静态资源 404、图片打不开、SEO 工具失效都是常态。
Apache 的 .htaccess 中如何跳过指定目录
关键不是“匹配要重写的路径”,而是“提前排除不该重写的路径”。用 RewriteCond 拦住就行:
- 想放行
static/目录:加一行RewriteCond %{REQUEST_URI} !^/static/ - 想同时放过
uploads/和robots.txt:RewriteCond %{REQUEST_URI} !^/(static|uploads)/和RewriteCond %{REQUEST_URI} !=/robots.txt - 注意顺序:所有
RewriteCond必须在RewriteRule前面,且按从上到下依次判断 - 别漏掉开头的
/:写成!^static/会匹配失败,因为%{REQUEST_URI}总是以/开头
完整示例(含常见排除):
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(static|uploads|themes|favicon.ico|robots.txt)
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
</ifmodule>
Nginx 配置里怎么绕过伪静态重写
Nginx 没有 RewriteCond,靠 location 优先级和 try_files 实现等效逻辑。核心是:先匹配静态路径,命中就直接返回,不进 PHP。
- 对
/static/目录:写location ^~ /static/ { alias /path/to/public/static/; }(注意结尾斜杠和alias路径) - 对单个文件如
robots.txt:location = /robots.txt { try_files $uri 404; } - 上传目录(如
/uploads/)必须显式声明,否则会被location /的try_files拦下来转给index.php - 别用
location ~ \.php$匹配来兜底——它不处理路径,只管后缀;真正要拦的是“路径前缀”
典型 Nginx 片段:
location ^~ /static/ {
alias /var/www/myapp/public/static/;
}
location ^~ /uploads/ {
alias /var/www/myapp/public/uploads/;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
ThinkPHP 路由层还能再过滤一次吗
不能。路由是在 index.php 启动后才执行的,而伪静态规则发生在 Web 服务器阶段(Apache/Nginx),早于 PHP 执行。所以「在 route/app.php 里写规则跳过某些路径」完全无效——请求根本到不了那里。
- 唯一例外是 ThinkPHP6 的「应用多入口」场景,比如你为
admin单独建了public/admin.php入口,那你可以给它配独立的 Nginxlocation,不走主重写规则 - 如果你发现某个目录被重写了但又没报错,大概率是
public下真有同名目录或文件,触发了!-d/!-f判断失败 - 调试时打开 Nginx 的
rewrite_log on(需编译支持)或 Apache 的RewriteLogLevel 3,看实际匹配路径
为什么排除后还是 404?常见断点位置
排除规则写了,但静态资源仍 404,问题往往不在规则本身,而在路径解析链路上的某一处断了:
-
alias路径末尾多了一个/:Nginx 中alias /path/和alias /path行为不同,后者更安全 - Apache 的
RewriteBase设错:比如项目部署在子目录/myapp/,但RewriteBase写成/,会导致重写后的index.php?/static/xxx路径错乱 - Linux 权限问题:Web 用户(如
www-data)没有读取static/目录的权限,403 比 404 更隐蔽 - ThinkPHP 的
public目录未设为 Web 根目录:很多新手把整个项目放 Web 根下,导致public/static/实际 URL 是/public/static/,但规则里写的是/static/
最稳的验证方式:curl -I http://yoursite/static/test.css,看响应头里的 200 和真实路径是否一致。不猜,只看响应。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











