如何解决 Nginx 实现动静分离或反向代理时资源路径不匹配
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 类型来指定替换指定类型的文件内容,而不是替换所有
总结如下:
版权声明: 本文为 InfoQ 作者【运维研习社】的原创文章。
原文链接:【http://xie.infoq.cn/article/cf58eab2d0a6e62d0d2256d91】。文章转载请联系作者。
评论