CentOS7下Apache部署Angular非首页路由报403/404故障排查
问题根因
两个错误分别对应不同的配置问题:
- 初始404是Angular单页应用的典型部署问题:Angular的前端路由(比如
/about)是浏览器端实现的,服务器对应路径下不存在同名物理文件/目录,Apache默认会查找物理资源,找不到就返回404。应用内跳转正常是因为路由跳转完全在浏览器端完成,没有向服务器发送对应路径的资源请求。 - 添加.htaccess后全路径403的核心原因是配置指令位置错误:你把
Require all granted直接写在了.htaccess文件根层级,Apache 2.4版本中这类目录授权指令不允许在未开启对应AllowOverride权限的前提下直接在.htaccess根节点使用,直接触发访问拒绝。
另外你原来写在.htaccess里的重写正则有缺陷:规则^(?!.*\.).*$会跳过所有带.的路径,如果你后续有类似/v1.0/info这类带点的路由,会再次触发404。
修复方案
优先把规则直接写在VirtualHost配置中(性能比.htaccess高,也能避免权限兼容问题),步骤如下:
- 修正站点目录权限
CentOS7下Apache默认运行用户为apache,先给站点目录分配正确权限,执行以下命令:
chown -R apache:apache /var/www/MyApp chmod -R 755 /var/www/MyApp
- 修改HTTPS对应的443端口VirtualHost配置
把原来的<Directory /var/www/MyApp/>块替换为以下内容:
<Directory /var/www/MyApp/html> Options Indexes FollowSymLinks AllowOverride None Require all granted RewriteEngine On # 直接返回真实存在的文件、目录请求 RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] # 其余所有请求全部转发给index.html,由Angular接管路由 RewriteRule ^ index.html [L] # 可选:你之前配置的无hash文件缓存禁用规则可以放在这里 <FilesMatch "^(?!.*\.([0-9a-z]{20})\.).*$"> <IfModule mod_headers.c> FileETag None Header unset ETag Header unset Pragma Header unset Cache-Control Header unset Last-Modified Header set Pragma "no-cache" Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Expires "Mon, 1 Jan 1900 00:00:00 GMT" </IfModule> </FilesMatch> </Directory>
- 删除之前放在
/var/www/MyApp/html目录下的错误.htaccess文件,避免规则冲突。 - 检查配置并重启服务
执行以下命令校验Apache配置语法:
httpd -t
确认返回Syntax OK后,重启Apache生效:
systemctl restart httpd
额外注意事项
- Angular构建时确认baseHref配置为
/,可以在构建命令中加参数ng build --prod --base-href /,或者在angular.json中对应构建配置项里设置baseHref: "/",避免静态资源加载路径错误。 - 如果坚持要使用.htaccess方式,需要先把Directory块中的
AllowOverride None改为AllowOverride All FileInfo Options AuthConfig,同时删除.htaccess文件开头单独写的Require all granted行,把重写规则替换为上面配置里基于REQUEST_FILENAME判断的版本即可。
内容的提问来源于stack exchange,提问作者user19545153
相关产品推荐
相关产品推荐

