Nginx 配置笔记

路由匹配规则

  • 优先级:精确匹配 > 前缀匹配 > 正则匹配 > 通用匹配

  • 语法示例

    nginx 复制代码
    # 精确匹配 localhost/home
    location =/home {...}
    
    # 前缀匹配 localhost/api/...
    # 前缀匹配会搜索所有前缀匹配的 location, 最后返回匹配最长的 location
    location ^~/api/ {...}
    
    # 正则匹配 localhost/static/.../file.jpg
    # ~ 区分大小写,~* 不区分大小写
    # !~ 区分大小写取非,!~* 不区分大小写取非
    location ~*/repo/.+\.(gif|jpg|jpeg)$ {...}
    
    # 通用匹配 localhost/index.html
    location / {...}
  • 可以捕获组获取匹配结果

    bash 复制代码
    # 根据环境名称设置路径
    location ^~/(staging|prod|dev)/ {
        root /dist/$1
    }

路径跳转:不同 location 之间跳转

  • 语法: rewrite <regex> <replacement> [flag];

    ruby 复制代码
    # 去除路径起始的环境名称
    location ^~/(staging|prod|dev) { 
        rewrite ^/(staging|prod|dev)/(.*)$ /$2 break; 
    }
  • flag 标记:

    • last :本条规则匹配完成后,不终止重写后的 url 匹配,浏览器地址栏不变
    • break :本条规则匹配完成即终止,终止重写后的 url 匹配,浏览器地址栏不变
    • redirect :返回 302 临时重定向,浏览器地址会显示跳转后的 URL 地址
    • permanent :返回 301 永久重定向,浏览器地址栏会显示跳转后的 URL 地址

根据环境名称设置路由

  • 文件目录结构:

    markdown 复制代码
    - dist
        - dev
            - index.html
            - assets
                - js/css/... 资源文件
        - prod
            - ...             
  • nginx 配置规则

    nginx 复制代码
    http {
        include mime.types;
        default_type application/octet-stream;
        # ...
        
        # 根据请求 url 获取环境名称: localhost/dev --> dev
        # 注意:map 需要位于 http {...} 中
        map $request_uri $env_name_uri {
            ~^/(staging|prod|dev)(/|$) $1;
            default "";
        }
        
        server {
            listen 443 ssl;
            server_name localhost;
            # ...
            
            # index 通过 url 获取环境名称,后续资源加载如果采用绝对路径就需要从 cookie 中获取环境名称
            set $env_name $env_name_uri;
            if ($env_name = "") {
                set $env_name $cookie_env;
            }
            add_header Set-Cookie "env=$env_name; Path=/; Max-Age=3600; HttpOnly; SameSite=Lax";
            
            # 动态设置 root 路径
            root /dist/$env_name;
            index index.html;
            
            location / {
                try_files $uri $uri/ /index.html;
            }
            
            # 处理环境特定路径, 重定向到不包含环境名称的路径
            location ^~/(staging|prod|dev) {
                rewrite ^/(staging|prod|dev)/(.*)$ /$2 break;
                try_files $uri $uri/ /index.html;
            }
            # 资源文件访问可能不会携带环境名称,从 cookie 获取环境名称
            location ^~/assets/ {
                root /dist/$env_name;
                try_files $uri $uri/ =404;
                expires 30d;
                access_log off;
                # 启用 Gzip 压缩
                gzip on;
                gzip_types text/css application/javascript image/svg+xml;
                gzip_min_length 1024;
                gzip_comp_level 6;
            }
            
            # api 根据不同环境配置不同的 host
            set $api_host "";
            if ($env_name = "staging") {
                set $api_host "http://127.0.0.1:8001";
            }
            if ($env_name = "prod") {
                set $api_host "http://127.0.0.1:8000";
            }
            location ^~/api/ {
                proxy_pass $api_host;
                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;
            }
            
            error_page 404 /404.html;
            error_page 500 502 503 504 /50x.html;
        }
    }

全局变量汇总

核心请求变量 说明
$args , $query_string 请求中的参数(Query String),如 ?name=john 中的 name=john
$is_args 如果请求有参数,值为 ?;否则为空字符串
$uri 当前请求的规范化 URI ‌(不含参数),如 /api/user
$request_uri 完整的原始请求 URI ‌(含参数),如 /api/user?name=john
$scheme 请求协议(httphttps
$request_method 请求方法(GETPOST 等)
$request_length 请求总长度(含请求行、请求头、请求体)
$request_body 请求体内容(通常用于 proxy_pass 或日志记录)
$remote_addr 客户端 IP 地址
$remote_port 客户端端口号
$server_addr 服务器 IP 地址
$server_port 服务器端口号
$server_name 匹配请求的 server 块中的 server_name
$host 优先级顺序 ‌: 1. 请求行中的 Host 头 2. server_name 匹配的域名 3. 配置中首个 server_name
相应相关变量
$status HTTP 响应状态码(如 200404
$body_bytes_sent 发送给客户端的响应体字节数(不含响应头)
$bytes_sent 发送给客户端的‌总字节数‌(含响应头)
$sent_http_* 任意响应头的值,如 $sent_http_content_type
连接与请求控制
$connection 连接序列号
$connection_requests 当前连接上的请求数量(用于 keepalive 连接)
$nginx_version Nginx 版本号
时间相关变量
$time_iso8601 ISO 8601 格式的本地时间(如 2023-10-05T14:31:12+08:00
$time_local 普通日志格式的本地时间(如 05/Oct/2023:14:31:12 +0800
$request_time 请求处理总耗时 ‌(单位:‌‌,精确到毫秒)
$upstream_response_time 上游服务器响应耗时(单位:秒)
代理相关变量
$proxy_host proxy_pass 指令中指定的上游主机名
$proxy_port proxy_pass 指令中指定的上游端口
$upstream_addr 上游服务器的 IP 和端口(如 192.168.1.23:8080
$upstream_status 上游服务器的 HTTP 响应状态码
$upstream_http_* 从上游服务器返回的响应头(如 $upstream_http_server
其他实用变量
$http_* 任意请求头的值$http_user_agent, $http_referer,$http_cookie
$cookie_* 获取特定 Cookie 值(如 $cookie_sessionid
$arg_* 获取特定 URL 参数 ‌(如 $arg_id 获取 ?id=123 中的 123
$document_root 当前请求的 rootalias 指令指定的根目录路径
$realpath_root $document_root 的绝对路径(符号链接解析后)
相关推荐
起个名特麻烦1 小时前
SpringBoot全局配置LocalDate/LocalTime/LocalDateTime的序列化和反序列化
java·spring boot·后端
高斯林.神犇2 小时前
四、依赖注入.spring
java·后端·spring
hero.fei2 小时前
在springboot中使用Resilience4j
java·spring boot·后端
会写代码的建筑师2 小时前
.NET 控制台后台程序实践细节总结
后端·.net
nghxni2 小时前
基于 HttpRequestSrv 的 HTTP Listener 与 Request 实战
后端
用户298698530142 小时前
后端一次搞定 HTML 转 PDF?不装浏览器也能干的简易方案
java·后端
Carsene2 小时前
AutoScan v1.2.0 发布 - 三大新特性,让你的 Spring Boot 包扫描更灵活、更高效!
spring boot·后端
MgArcher2 小时前
Python高级特性:生成器完全指南
后端
用户3754268434032 小时前
从零构建 Go IM 系统:WebSocket + AI Agent + gRPC 全栈实践
后端