用Nginx提供子目录index.html服务时,如何避免无末尾斜杠请求导致资源失效
Nginx 子目录默认页访问不带斜杠时资源失效问题解决
原始配置与实际表现
当前线上生效的配置片段如下:
location ^~ /folder { try_files $uri $uri/index.html $uri.html =404; } location / { # 常规站点的业务处理逻辑 }
对应站点的目录结构为:/folder 挂载路径下没有直接存放可访问的实体文件,仅包含多级嵌套的子目录,每个子目录中都存放独立的index.html作为该目录的默认入口页。
符合预期的访问场景
- 访问站点根路径
mywebsite.com:正常返回常规站点的全部内容 - 访问
mywebsite.com/folder:按配置规则返回404,和预期一致 - 访问带末尾斜杠的子路径
mywebsite.com/folder/subfolder/:正常返回对应子目录下的index.html,页面内引用的CSS、JS、图片等静态资源全部可正常加载
异常故障场景
访问不带末尾斜杠的子路径 mywebsite.com/folder/subfolder 时,虽然接口能正确返回对应子目录的index.html内容,但页面内所有静态资源全部加载失败。
问题根源
出现这个问题的逻辑很直白:浏览器解析页面内的相对资源路径时,是根据当前地址栏的URL层级计算加载路径的。当访问地址是不带斜杠的/folder/subfolder时,浏览器会判定当前所在层级是/folder/,页面内写的style.css这类相对路径资源,自然会被解析为从/folder/目录下加载,也就是请求/folder/style.css,和资源实际存放的/folder/subfolder/style.css路径完全不匹配,自然全部加载失效。
之前的配置没有触发Nginx对目录路径自动补末尾斜杠的跳转逻辑,浏览器一直停留在不带斜杠的错误地址上做资源解析,最终出现资源全部404的问题。
解决方案
将该location块下的try_files规则调整为如下顺序即可:
location ^~ /folder { try_files $uri $uri/ $uri.html =404; }
规则生效逻辑:当请求的路径是不带斜杠的目录路径时,$uri/判断规则会触发Nginx内置的目录自动跳转逻辑,自动返回301响应把路径补全为带末尾斜杠的格式,浏览器跳转后会基于正确的目录层级解析相对资源路径,静态资源的加载路径就会匹配正确,不会再出现偏移失效的问题。
调整后,访问不带斜杠的子路径时会先触发一次自动301跳转到带斜杠的同目录路径,属于Nginx的标准内置行为,不存在功能异常,仅多一次跳转过程。
内容的提问来源于stack exchange,提问作者Armag3ddon
相关产品推荐
相关产品推荐

