nginx访问静态资源的相关配置

nginx访问静态资源的相关配置

引言

需要通过nginx服务读取静态文件,需要配置nginx.conf的相关配置,如虚拟主机配置server、location配置。
其实nginx.conf的配置文件是由指令集组成的,指令集分为:简单指令、模块指令。
简单的指令由名字和参数组成,中间用空格隔开,末尾用分号(;)结尾。
模块指令和简单指令有着相同的结构,但是末尾的分号(;)改为了花括号({}
如果模块指令中含有其它的模块指令,那么该模块指令就叫做上下文(context),比如http模块指令、server模块指令。

1、server模块指令

server模块指令是nginx用来配置虚拟主机的
什么是虚拟主机?


pic-1590651964374.png

server模块指令中有三个重要的指令:listen 监听端口号,server_name 服务名,location映射解析文件地址


pic-1590651964375.png

2、location模块指令

向server模块指令添加location模块指令如下:
location / {
    root 文件地址
}

如下:


pic-1590651964376.png

解释这段指令:

location中指定的“/html”会和请求的uri做比较,如果符合,那么uri会加载到root指令集中指定的路径“E:\javaWork\XXXX\0521”后面。
举个例子说明:如果在浏览器的地址栏写上/html/23/24/xx.html的话,那么因为uri里含有html,那么就能够匹配到这个location指定的“/html"。
所以完整的映射文件解析地址是:E:\javaWork\XXXX\0521\html\23\24\xx.html
前半部分加下划线的就是root指令集指定的路径,后半部分是匹配得到的uri。

(1)一个目录可以对应多个location指令集

这样的话,一个文件的目录可以写成多个location指令进行匹配,因为最后访问的话是根据root指令集所指的地址 加上 location指定的uri拼接的

就拿上面E:\javaWork\XXXX\0521\html\23\24这个目录通过root指令对应的的地址location指定的uri拼接能够得到的方式有:(举几种,不举全)
(1)root E:\javaWork\XXXX\0521; location \html\23\24;
(2)root E:\javaWork\XXXX\0521\html; location \23\24;
(3)root E:\javaWork\XXXX\0521\html\23; location \24;

如果server指令集写的端口是8084,server_name是localhost。

那么上面的三种root指令集对应的地址和location对应的uri拼接情况,可以通过以下三种方式取到 \24 目录下对应的静态文件。

(1)localhost:8084/html/23/24/xx.html (匹配第一个对应的location指令集)
(2)localhost:8084/23/24/xx.html  (匹配第二个对应的location指令集)
(3)localhost:8084/24/xx.html   (匹配第三个对应的location指令集)

(2)优先更全的uri匹配原则(精确匹配原则)

如果两个不同的目录有以下两个location指令对应

(1)
    location /0521 {
        root E:/java/jvm;
    }
(2)
    location /0521/doc {
        root D:/java/gc;
    }

这时,如果在浏览器地址栏访问localhost:8084/0521/doc/hello.html
(1)假设E:/java/jvm/0521目录下有doc文件夹,并且里面有hello.html静态文件。
(2)假设D:/java/gc/0521/doc目录下,有hello.html静态文件。

这一步是不是给弄懵逼了?请求的uri符合这两个location指令的匹配,那么具体匹配哪一个呢?
那就是按照精确匹配原则,哪个location对应的uri更加和请求的uri精确,那么就匹配哪个location指令集。也就是说,在上面那个问题中,会匹配第二个location指令集

证明上面结论:

(1)创建测试文件

D盘符文件,及hello.html内容:


pic-1590651964378.png

E盘符文件,及hello.html内容:


pic-1590651964380.png

(2)给nginx.conf增加两个location指令集


pic-1590651964382.png

(3)重新加载nginx.conf配置文件

使用  nginx -s reload 命令重新加载nginx.conf配置文件

(4)浏览器地址栏访问:localhost:8084/0521/doc/hello.html

对吧?匹配的就是指向D盘的那个location。 如果所匹配的location并不是你所期望的那样或者诸如此类的其它问题,那么你可以去查看logs目录下的error.log和access.log这两个日志文件。


pic-1590651964384.png

(3)一个请求始终只匹配最精确的location

到这里,再抛出一个问题,接着上面的操作,精确匹配确实是匹配到了指向D盘的location,那么,如果我要匹配的文件在doc目录下,并没有呢?nginx会对浏览器发出的请求如何处理,是直接抛出404吗?

我们可以尝试着将第二个location对应的目录下的hello.html进行删除,再去访问localhost:8084/0521/doc/hello.html;看看是否会访问E盘下的hello.html

结果显然,并不会去匹配第一个映射E盘的location,也就是说,如果uri已经匹配到当前这个精确location的话,那么如果没有需要访问的文件,那么直接抛出404,而不会去继续匹配其它的不精确的location。

(4)额外注意

这段话是个人总结的,网上没见着相关结论。
location的映射文件地址是root对应地址加上location的uri。E:\javaWork\XXXX\0521\html\23\24)
如果要访问这个地址 E:\javaWork\XXXX\0521\html\23\24) 的前一层或前几层目录下的文件,那么只能通过匹配另外的location。并不能通过相对路径(..)的形式访问到。

我们让一个文件地址匹配两个location指令,如下图:

(1)匹配的第一个location,这个location的文件映射地址是:E:\javaWork\XXX\0521\html


(2)匹配的第二个location,这个location的文件映射地址是:E:\javaWork\XXX\0521\html\static\html\self_test

我们可以看见页面报错了,是由于页面用到的jquery没有正确引入。
这是为什么?因为磁盘上没有吗?可是第一个location映射文件地址是可以的,所以显然 并不是 这个原因。
这是因为nginx通过这个location,只读取了E:\javaWork\XXX\0521\html\static\html\self_test目录下的文件进来。而jquery文件,并不在这个目录下。
也就是说,nginx只会读取location映射的文件地址下的所有文件,除此目录外的文件一律获取不到。

参考资料

(1)nginx基础应用
(2)nginx.conf配置文件解析(http、server、location)

posted @ 2020-05-28 16:00  林就远  阅读(11119)  评论(0编辑  收藏  举报