伪静态后图片/css/js 404,是因为重写规则将所有请求(包括真实静态资源)转发至index.php,而thinkphp不处理这些资源;正确做法是用apache的rewritecond或nginx的try_files在转发前识别并放行真实文件。

为什么伪静态后图片/CSS/JS 404?
因为重写规则把所有请求都转给了 index.php,连 /static/css/app.css 这类真实存在的静态资源也进了路由层,而 ThinkPHP 不处理它们,最终返回 404。
关键不是“要不要放行”,而是“怎么让服务器在转发前就识别出这是真实文件”——靠 RewriteCond(Apache)或 try_files(Nginx)提前拦截。
Apache 下如何跳过真实静态文件?
必须用两个 RewriteCond 判断:当前请求路径既不是目录,也不是真实文件。缺一不可,否则子目录或同名 PHP 文件可能被误放行。
-
RewriteCond %{REQUEST_FILENAME} !-d:排除真实存在的目录(如/uploads/) -
RewriteCond %{REQUEST_FILENAME} !-f:排除真实存在的文件(如/favicon.ico、/static/js/main.js) -
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]:只对不匹配前两者的路径生效
注意:.htaccess 必须放在 public 目录(即 index.php 所在目录),且 Apache 的 AllowOverride 需设为 FileInfo Options 或 All,否则条件判断不执行。
Nginx 中 try_files 比 if 更可靠
用 if (!-e $request_filename) 是常见写法,但 Nginx 官方明确不推荐在 location 块中使用 if,它在某些嵌套场景下会失效或产生意外重定向。
正确做法是用 try_files 顺序匹配:
location / {
try_files $uri $uri/ /index.php?s=$uri&$args;
}
含义:先查 $uri(如 /logo.png),再查 $uri/(如 /admin/),都不命中才交给 index.php。这个顺序天然绕过所有真实静态资源,无需额外判断。
如果项目部署在二级目录(如 /myapp/),则需调整 try_files 第三项为 /myapp/index.php?s=$uri&$args,否则路由参数 s 会丢失路径前缀。
ThinkPHP 自身要不要额外配置?
不需要。框架层面只负责解析 PATH_INFO 或 QUERY_STRING 中的 s=xxx,它不参与静态文件判定。真正决定“谁该被放行”的是 Web 服务器本身。
唯一要注意的是:确保 public 目录是 Web 根目录(不是项目根目录),否则 $uri 和 $request_filename 的路径基准就错了——这是 80% 的 Nginx 404 真正原因,而不是规则写得不对。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











