Yii2高级模板CentOS生产环境样式脚本403错误排查求助
这种情况我在部署Yii2项目时碰到过好几次,结合你用的Yii2-advanced模板和CentOS生产环境,大概率是下面这几个原因导致的,你可以一个个排查看看:
1. Apache未允许.htaccess生效(最常见)
Yii2的backend/web目录下默认有个.htaccess文件,里面的Rewrite规则专门用来区分静态资源和动态请求:静态资源直接交给Apache返回,只有动态请求才转发到index.php处理。如果你的VirtualHost配置里没开启AllowOverride All,这个.htaccess就完全不起作用——所有请求(包括css、js文件)都会被强制转发到Yii的入口脚本。Yii找不到对应路由的话,就会返回403错误;但你直接访问静态资源的真实路径时,Apache会直接读取文件返回,所以状态码是200。
解决方法:
在你的VirtualHost配置块里,给DocumentRoot对应的目录加上权限配置,同时确保mod_rewrite模块已经启用:
<VirtualHost *:443> ServerName cp.tickets.site.ru ServerAdmin osd@site.ru DocumentRoot "/var/www/vhost/tickets.site.ru/htdocs/backend/web" # 新增这段配置,允许.htaccess生效 <Directory "/var/www/vhost/tickets.site.ru/htdocs/backend/web"> AllowOverride All Require all granted </Directory> # 你的SSL相关配置... </VirtualHost>
修改完成后重启Apache服务:
systemctl restart httpd
2. Yii2的UrlManager规则太严格,未排除静态资源
如果你的backend/config/main.php里的UrlManager开启了enableStrictParsing(严格解析),但没添加静态资源的排除规则,Yii会把所有请求都当作路由来处理——包括css、js的请求,自然找不到对应的控制器动作,返回403。
解决方法:
检查UrlManager的配置,添加静态资源的排除规则:
'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'enableStrictParsing' => true, // 若开启了严格解析,必须加排除规则 'rules' => [ // 排除所有常见静态资源后缀的请求 '<file:[\w\-\.]+\.(css|js|png|jpg|jpeg|gif|ico|svg)>', // 你的其他路由规则... '<controller:\w+>/<action:\w+>' => '<controller>/<action>', ], ],
如果enableStrictParsing是false,一般不会出现这个问题,但加上排除规则能避免后续的意外问题。
3. SELinux上下文限制(CentOS特有)
CentOS默认开启SELinux,哪怕文件的权限是755,如果SELinux的上下文标记不对,Apache可能无法通过Rewrite规则访问静态资源(但直接访问时能绕过限制返回200)。这种情况多发生在你用root用户上传部署文件的场景。
解决方法:
给backend/web目录设置正确的SELinux上下文:
chcon -Rv --type=httpd_sys_content_t /var/www/vhost/tickets.site.ru/htdocs/backend/web
如果项目需要Apache写入文件(比如assets目录),还要额外设置写入权限的上下文:
chcon -Rv --type=httpd_sys_rw_content_t /var/www/vhost/tickets.site.ru/htdocs/backend/web/assets
4. Yii2的RBAC权限控制误拦截
如果你在项目里配置了RBAC(基于角色的权限控制),并且设置了全局的访问过滤规则,有可能把静态资源的请求也当成了需要权限验证的动作,从而返回403。
解决方法:
检查backend/config/main.php里的as access配置,添加静态资源的允许规则:
'as access' => [ 'class' => 'yii\filters\AccessControl', 'rules' => [ [ 'allow' => true, 'actions' => ['login', 'error'], ], [ 'allow' => true, 'roles' => ['@'], ], // 新增:允许所有静态资源请求 [ 'allow' => true, 'matchCallback' => function ($rule, $action) { $request = Yii::$app->request; return preg_match('/\.(css|js|png|jpg|jpeg|gif|ico|svg)$/', $request->url); }, ], ], ],
内容的提问来源于stack exchange,提问作者Камалов Радик

