zoukankan      html  css  js  c++  java
  • 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:javaWorkXXXX521”后面。
    举个例子说明:如果在浏览器的地址栏写上/html/23/24/xx.html的话,那么因为uri里含有html,那么就能够匹配到这个location指定的“/html"。
    所以完整的映射文件解析地址是:E:javaWorkXXXX521html2324xx.html
    前半部分加下划线的就是root指令集指定的路径,后半部分是匹配得到的uri。

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

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

    就拿上面E:javaWorkXXXX521html2324这个目录通过root指令对应的的地址location指定的uri拼接能够得到的方式有:(举几种,不举全)
    (1)root E:javaWorkXXXX521; location html2324;
    (2)root E:javaWorkXXXX521html; location 2324;
    (3)root E:javaWorkXXXX521html23; 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:javaWorkXXXX521html2324)
    如果要访问这个地址 E:javaWorkXXXX521html2324) 的前一层或前几层目录下的文件,那么只能通过匹配另外的location。并不能通过相对路径(..)的形式访问到。

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

    (1)匹配的第一个location,这个location的文件映射地址是:E:javaWorkXXX521html


    (2)匹配的第二个location,这个location的文件映射地址是:E:javaWorkXXX521htmlstatichtmlself_test

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

    参考资料

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

  • 相关阅读:
    CF1314G解题报告
    CF1310D解题报告
    CF1310B解题报告
    CF908G解题报告
    oracle的IMU和ora-01555
    oracle事物
    oracle中scn(系统改变号)
    oracle实例恢复之检查点队列
    oracle优化:避免全表扫描(高水位线)
    关于oracle中in和exists的区别
  • 原文地址:https://www.cnblogs.com/xm970829/p/12981429.html
Copyright © 2011-2022 走看看