配置Nginx静态文件访问

未分类 1683 字 发布于 2026-04-04 最后更新于 2026-04-04


    # 外网服务配置(监听10005端口)
    server {
        listen       10005;
        server_name  60.2.xx.xx;

        # 前端Vue静态资源
        location /tos-web {
            alias   D:/kstos/web/apache-tomcat-8.5.85/webapps/tos-web;  # 替换为实际前端dist目录路径
            index  index.html index.htm;
            try_files $uri $uri/ /tos-web/index.html;
        }

        # 后端API代理(外网)
        location /tos {
            proxy_pass http://60.2.xx.xx:10006/tos;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            
            # WebSocket支持(如果需要)
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }

        # 静态文件
        location /images/ {
			# !!!注意这里改成了 root,并且路径少了一层 /images/ !!!
            # 原理:root 会把 "location 后的 URL" 自动拼接到 "root 指定的路径" 后面
            # 拼接逻辑:D:/kstos/files/ + /images/indexImg/gis.png
            root D:/kstos/files/;           # 物理路径
            autoindex off;                  # 禁止列出整个目录
            allow all;                      # 允许所有人访问
        }
    }

这是一个非常经典也是非常重要的 Nginx 基础问题。弄清楚这两点,能帮你避免 80% 的 404 错误。

我将其拆解为两个部分来详细讲解。


第一部分:location​ 后面加不加斜杠的区别

​location /images​ location /images/​ 的核心区别在于 ​匹配的精确度​(前缀匹配 vs 目录匹配)。

1. 不加斜杠:location /images​

这是 ​普通前缀匹配​。只要 URL 以 /images​ 开头,都会匹配上。

  • 配置:
  • 匹配情况:
    • ​http://.../images/1.jpg​ -> ✅ 匹配
    • ​http://.../images/index.html​ -> ✅ 匹配
    • ​http://.../images-old/1.jpg​ -> ✅ 匹配! (注意这里)
    • ​http://.../images_2023/1.jpg​ -> ✅ 匹配!

潜在风险: 如果你只想匹配 images​ 目录,但不想匹配到 images-old​ 或 images_backup​,不加斜杠就会导致误匹配,可能暴露你不希望公开的备份目录。

2. 加斜杠:location /images/​

这是 ​目录匹配​。它明确告诉 Nginx,这是一个文件夹。

  • 配置:
  • 匹配情况:
    • ​http://.../images/1.jpg​ -> ✅ 匹配
    • ​http://.../images-old/1.jpg​ -> ❌ 不匹配 (因为 /images-old​ 不是以 /images/​ 开头的)

✅ 最佳实践:

如果你是在配置一个静态资源目录,强烈建议加上斜杠 /​,这样更安全,也能减少不必要的歧义。


第二部分:root​ 和 alias​ 的区别

这是最容易导致 404 的地方。简单来说:

  • root 是 ​拼接​(追加)。
  • alias 是 ​替换​。

1. root (拼接模式)

​root​ 会把你请求的 URL 完整地拼接到 root​ 指定的路径后面。

  • ​场景​:你要访问 http://.../images/1.jpg​
  • ​配置​:
  • ​Nginx 寻找文件的物理路径计算公式​:
    ​root 路径​ + 完整 URL​
    = /data/www​ + /images/1.jpg​
    = /data/www/images/1.jpg​

特点: 你的硬盘上必须真实存在一个 images​ 文件夹,且在 /data/www​ 下面。硬盘结构必须和 URL 结构保持一致。

2. alias (替换模式)

​alias​ 会把 location​ 后面匹配到的部分 ​丢弃​,用 alias​ 指定的路径来 替换 它。

  • ​场景​:你要访问 http://.../images/1.jpg​
  • ​配置​:
  • ​Nginx 寻找文件的物理路径计算公式​:
    ​alias 路径​ + (完整 URL - location 部分)​
    = /data/www/photos/​ + 1.jpg​ (去掉 /images/)
    = /data/www/photos/1.jpg​

特点: 硬盘上的文件夹名字叫 photos​,但你想让用户通过 /images/​ 来访问。它允许 URL 和硬盘目录名不一样。


总结对比表

特性root (根路径)alias (别名)
逻辑​追加​:root + URI​替换​:alias + (URI - location)
硬盘目录要求硬盘目录结构必须包含 location 定义的文件夹名硬盘目录可以是任意名字,不需要和 location 一致
使用场景绝大多数情况,尤其是目录结构规范时当你需要把 URL 映射到一个完全不同名字的目录时
斜杠敏感度不敏感​非常敏感​:如果 location 有/​,alias 末尾最好也带/​

结论:

虽然在这个例子里,算出来的最终路径是一模一样的,但 ​root​ 的容错率更高,不易出错​。在 Windows 环境下,alias​ 有时会因为路径斜杠处理不当出 bug,而 root​ 逻辑简单粗暴,所以更推荐使用 root​。

没问题。追求配置的简洁和高效是非常好的运维习惯,越冗长的配置越容易出错。

采用白名单机制后,我们可以直接删掉那堆防范脚本的黑名单代码,用两行代码完成更高级别的防御。

这是为你整理好的完整、纯净且包含图床/视频流优化的最终版本。你可以直接复制并替换你原来的 server​ 块:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name demo3.661366.xyz;

    # SSL 证书配置
    ssl_certificate /etc/letsencrypt/live/661366.xyz-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/661366.xyz-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # 后端 API / 动态请求代理
    location / {
        proxy_pass http://localhost:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    # 静态媒体资源 (图片与视频)
    location /images/ {
		# 物理路径
        alias /home/images/tos/; 
		# 禁止列出整个目录
        autoindex off;

        # =========================================================
        # 1. 核心安全:白名单过滤 (最简洁的防马方式)
        # 仅放行图片和视频后缀,其余请求直接 403 拒绝
        # =========================================================
        if ($uri !~* \.(jpg|jpeg|png|gif|webp|avif|mp4|webm|m3u8|ts|ico)$) {
            return 403;
        }

        # =========================================================
        # 2. 防盗链:保护你的服务器带宽
        # =========================================================
        valid_referers none blocked server_names *.661366.xyz 661366.xyz;
        if ($invalid_referer) {
            return 403;
        }

        # =========================================================
        # 3. 性能优化:大文件与视频拖拽支持
        # =========================================================
        sendfile on;
        tcp_nopush on;
        mp4;
        mp4_buffer_size 1m;
        mp4_max_buffer_size 5m;

        # =========================================================
        # 4. 浏览器缓存与安全响应头
        # =========================================================
        expires 30d;
        add_header Cache-Control "public, no-transform";
        add_header X-Content-Type-Options nosniff;
        
        # 允许跨域 (如果你的主站和这个域名不同,视频播放器会需要这个)
        add_header Access-Control-Allow-Origin *; 
    }
}

为什么这个版本是“最高效”的?

  • 没有冗余逻辑: 把繁琐的“禁止 php、禁止 sh、禁止 jsp”等一长串黑名单,变成了一句干净利落的 if ($uri !~* ...)​。非白名单后缀连 Nginx 处理的门槛都进不去。
  • 按优先级排布: Nginx 每次处理请求都是从上到下执行。先把白名单和防盗链放在最前面,遇到恶意请求直接 return 403​ 中断处理,极其节省服务器资源。如果放在后面,Nginx 还要白白读取文件头信息。
  • 媒体专属引擎: 开启了 mp4​ 和 sendfile​,Nginx 会以流媒体服务器的工作模式来传输文件,极大提升视频的起播速度。

替换完成后,记得在终端运行 nginx -t​ 测试一下。需要我帮你看看如何平滑重载(不中断现有连接)Nginx 吗?

最后更新于 2026-04-04