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 的绝对路径(符号链接解析后)
相关推荐
前端一小卒6 小时前
我用 Claude Code 的 Superpowers 技能链写了个服务,部署前差点把服务器搞炸
前端·javascript·后端
曹牧7 小时前
Spring:@RequestMapping注解,匹配的顺序与上下文无关
java·后端·spring
阿丰资源9 小时前
SpringBoot+Vue实战:打造企业级在线文档管理系统
vue.js·spring boot·后端
Rust研习社9 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
0xDevNull9 小时前
Spring Boot 自动装配:从原理到实践
java·spring boot·后端
IT_陈寒10 小时前
SpringBoot配置加载顺序把我坑惨了
前端·人工智能·后端
Moment10 小时前
面试官:给 llm 传递上下文,有哪几个身份 role ❓❓❓
前端·后端·面试
snakeshe101010 小时前
SpringBoot 多人协作平台实战(5):从零开始集成 MyBatis ORM 连接 MySQL 数据库
后端
SamDeepThinking10 小时前
中小团队需要一个资源微服务
后端·微服务·架构
超梦dasgg11 小时前
Spring AI 智能航空助手项目实战
java·人工智能·后端·spring·ai编程