nginx中经常会因为业务需求,需要通过location配置不同的子目录,访问不同的后端,如下
这个时候,通常会遇到两种情况,如果说做了动静分离,静态资源单独location来配置,那通常没有问题
另外一种情况,就是没做静态分离,这时候,如果通过location 子目录的方式去配置nginx反向代理,或者配置location 子目录访问的时候,就会遇到问题,具体下面分析
就拿配置子目录的方式来分析,简单写了个html,引入一个js,js很简单就一个alert
js的代码如下:
配置好nginx,直接访问结果如下:
以上是正常配置在location /的情况,资源访问都正常,接着我们改下,用子目录的方式,把上面的html和js复制一套,改下内容,改完之后,nginx配置如下:
web目录结构如下:
配置好之后,加目录访问
查看js的headers可以发现test.js访问的是父目录下的test.js
我们看下index.html引入js的代码
从上面nginx配置分析可以发现,这个js的请求会匹配到location /,所以会访问到父目录,而不是子目录
上面这种静态资源相对路径引入方式,应该是很常见的写法(原谅一个运维不太懂前端)
因为我这里,父目录和子目录的js文件名称正好相同,所以虽然访问到的是错误的,但是可以请求到这个资源,很多时候,我们常遇到的情况是静态资源404,就是因为你原本想要它访问的地址是
https://域名/子目录/xxx.js
但是,实际客户端请求到nginx,获取到index.html,在浏览器渲染的时候,解析出来,拼接好的静态资源地址是
https://域名/xxx.js
这种情况,除了让开发手动去更改,还可以通过nginx的sub_filter来修改nginx响应内容,模块怎么添加就不多说了,有兴趣,可以专辑里面看看其他文章,里面都有介绍,所以这里默认sub模块已经有
还是刚才的子目录,我们配置sub_filter,替换响应中的/test.js部分,添加子目录/mulu1/test.js,配置如下:
重启nginx后,重新访问
可以看到返回的是mulu1下js的内容,我们看下test.js的header
如果是反向代理到不同的后端,同理,在location中将响应修改后再发送给客户端就可以修改客户端解析的静态资源地址,从而访问到想要的location中
nginx的sub模块很简单,就4个指令,分别是
sub_filter
sub_filter_last_modified
sub_filter_once
sub_filter_types
sub_filter,就是替换指令,有两个参数,第一个是原字符串,第二个是目标字符串
sub_filter_last_modified指令,是允许再替换期间,保留原始响应头中的Last-Modified字段,用来响应缓存,默认情况下是关闭的,就是在修改响应内容的时候,会删除标头字段
sub_flter_once指令,是指定替换一次还是替换所有匹配到的字符串,默认是on,替换第一次匹配到的,注意是第一次,不是第一个
sub_filter_types指令,是可以根据MIME类型来指定替换指定类型的文件内容,而不是替换所有
总结如下: