{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2019-12-20 16:03:25","updateBy":"admin","updateTime":"2025-06-18 21:32:50","remark":null,"id":8,"articleTitle":"Nginx（二）location模块","articleUrl":"nginx_location","articleThumbnail":"https://www.asumimoe.com/imgfiles/20250618/4b57c2e46f8949e5a30d4e2e9e8a8fd5.png","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"location模块是 Nginx 配置中最核心的路由控制单元，负责根据请求 URI 匹配不同的处理规则。它决定了 Nginx 如何处理客户端请求，是配置反向代理、负载均衡、静态资源服务的基石。","articleContent":"`location` 模块是 Nginx 配置中最核心的路由控制单元，负责根据请求 URI 匹配不同的处理规则。它决定了 Nginx 如何处理客户端请求，是配置反向代理、负载均衡、静态资源服务的基石。\n\n## 核心作用\n\n1. **URI 路由**：将不同路径的请求导向特定处理逻辑\n2. **请求处理**：定义静态文件服务、代理转发、重定向等行为\n3. **策略分离**：实现动静分离、API 版本控制等架构设计\n\n## 基础语法结构\n\n```nginx\nlocation [匹配模式] URI {\n    # 处理指令\n    proxy_pass, root, try_files, rewrite...\n}\n```\n\n---\n\n## 匹配模式详解\n\n| 模式       | 符号 | 匹配规则                     | 优先级 | 示例                      |\n| ---------- | ---- | ---------------------------- | ------ | ------------------------- |\n| 精确匹配   | `=`  | 完全匹配 URI（不含查询参数） | 最高   | `location = /login`       |\n| 优先前缀   | `^~` | 前缀匹配，跳过正则检查       | 次高   | `location ^~ /static`     |\n| 正则匹配   | `~`  | 区分大小写的正则匹配         | 中     | `location ~ \\.php$`       |\n| 忽略大小写 | `~*` | 不区分大小写的正则匹配       | 中     | `location ~* \\.(jpg|png)` |\n| 普通前缀   | 无   | 常规前缀匹配                 | 最低   | `location /api`           |\n\n### 1. `=`（精确匹配）\n\n- **语法**：`location = /uri { ... }`\n\n- **作用**：仅匹配完全相同的 URI（不含查询参数）。\n\n- **优先级**：最高（立即停止搜索）。\n\n- **示例**：\n\n  ```nginx\n  location = /login {\n      # 仅匹配 /login（不匹配 /login/ 或 /login?user=xxx）\n      proxy_pass http://backend;\n  }\n  ```\n\n### 2. `^~`（优先前缀匹配）\n\n- **语法**：`location ^~ /prefix { ... }`\n\n- **作用**：匹配以指定前缀开头的 URI，**一旦匹配成功，不再检查正则表达式**。\n\n- **优先级**：高于正则匹配（`~` 和 `~*`）。\n\n- **示例**：\n\n  ```nginx\n  location ^~ /static/ {\n      # 匹配 /static/js/app.js 等，跳过后续正则检查\n      root /var/www;\n  }\n  ```\n\n### 3. `~`（区分大小写的正则匹配）\n\n- **语法**：`location ~ \\.php$ { ... }`\n\n- **作用**：使用正则表达式匹配 URI，**区分大小写**。\n\n- **优先级**：按配置文件中的顺序匹配（第一个匹配成功即生效）。\n\n- **示例**：\n\n  ```nginx\n  location ~ \\.php$ {\n      # 匹配 .php 结尾的 URI（如 /index.php）\n      fastcgi_pass php:9000;\n  }\n  ```\n\n### 4. `~*`（不区分大小写的正则匹配）\n\n- **语法**：`location ~* \\.(jpg|png)$ { ... }`\n\n- **作用**：使用正则表达式匹配 URI，**不区分大小写**。\n\n- **优先级**：与 `~` 相同，按顺序匹配。\n\n- **示例**：\n\n  ```nginx\n  location ~* \\.(jpg|png)$ {\n      # 匹配 .jpg、.JPG、.png、.PNG 等\n      expires 30d;\n  }\n  ```\n\n### 5. 无修饰符（普通前缀匹配）\n\n- **语法**：`location /some/prefix { ... }`\n\n- **作用**：匹配以指定前缀开头的 URI。\n\n- **优先级**：最低（会被 `^~` 和正则匹配覆盖）。\n\n- **示例**：\n\n  ```nginx\n  location /images/ {\n      # 匹配 /images/logo.png 等\n      root /data;\n  }\n  ```\n\n### 6.匹配优先级规则总结\n\nNginx 按以下顺序选择 `location`：\n\n1. **精确匹配** `=`（最高优先级）。\n2. **优先前缀匹配** `^~`（匹配后停止正则检查）。\n3. **按配置文件顺序**的正则匹配（`~` 或 `~*`）。\n4. **普通前缀匹配**（无修饰符，若多个匹配则选最长前缀）。\n\n### **示例配置**\n\n```nginx\nserver {\n    # 1. 精确匹配（最高优先级）\n    location = / {\n        return 200 \"Root path\";\n    }\n\n    # 2. 优先前缀匹配（跳过正则）\n    location ^~ /static/ {\n        root /var/www;\n    }\n\n    # 3. 区分大小写的正则匹配\n    location ~ \\.php$ {\n        fastcgi_pass unix:/run/php.sock;\n    }\n\n    # 4. 不区分大小写的正则匹配\n    location ~* \\.(jpg|png)$ {\n        expires 7d;\n    }\n\n    # 5. 普通前缀匹配（最低优先级）\n    location / {\n        try_files $uri $uri/ =404;\n    }\n}\n```\n\n### 匹配优先级规则\n\n当多个 location 同时匹配时，按以下顺序选择：\n\n1. **精确匹配** (`=`) → 立即生效\n2. **优先前缀匹配** (`^~`) → 匹配后停止正则检查\n3. **正则匹配** (`~` 或 `~*`) → 按配置文件顺序匹配\n4. **普通前缀匹配** → 选择最长匹配的前缀\n\n> \uD83D\uDCCC **示例冲突解析**：  \n> 请求 `/static/image.jpg` 的匹配顺序：  \n>\n> 1. `location /static` (普通前缀)  \n> 2. `location ^~ /static` (优先前缀) → 命中  \n> 3. `location ~* \\.jpg$` (正则) → 被跳过\n\n## 核心处理指令\n\n### 1.`proxy_pass`（反向代理）\n\n将请求转发到后端服务器（如 Tomcat、Node.js、Python 应用等）  \n\n```nginx\nlocation /api/ {\n    proxy_pass http://backend_server;  # 可以是 IP、域名或 upstream 名称\n    proxy_set_header Host $host;       # 传递原始主机头\n    proxy_set_header X-Real-IP $remote_addr;  # 传递客户端真实 IP\n}\n```\n\n### 2. `try_files`（文件存在性检查）\n\n按顺序检查文件/路径是否存在，直到成功匹配  \n\n```nginx\nlocation / {\n    try_files $uri $uri/ /index.html;  # 检查顺序：1.文件 2.目录 3.回退文件\n}\n```\n\n### 3. `rewrite`（URL 重写）\n\n修改请求 URI 路径（常配合 `break` 或 `last` 标志）  \n\n```nginx\nlocation /old {\n    rewrite ^/old/(.*)$ /new/$1 permanent;  # 301 重定向\n}\n\nlocation /shop {\n    rewrite ^/shop/(\\d+)$ /product?id=$1 break;  # 内部重写（不改变浏览器地址）\n    proxy_pass http://product_service;\n}\n```\n\n### 4. `return`（直接返回响应）\n\n立即返回 HTTP 状态码或重定向  \n\n```nginx\nlocation /deny {\n    return 403 \"Access Denied\";  # 直接返回 403\n}\n\nlocation /redirect {\n    return 301 https://newdomain.com$request_uri;  # 301 重定向\n}\n```\n\n---\n\n### 5. `alias`（路径别名）\n\n映射文件系统路径（与 `root` 不同，会替换匹配路径）  \n\n```nginx\nlocation /static/ {\n    alias /var/www/app/assets/;  # /static/logo.png → /var/www/app/assets/logo.png\n}\n```\n\n---\n\n### 6. `root`（设置根目录）\n\n定义文件服务的根路径  \n\n```nginx\nlocation /images/ {\n    root /data/web/;  # /images/cat.jpg → /data/web/images/cat.jpg\n}\n```\n\n---\n\n### 7. `fastcgi_pass`（PHP/Python 转发）\n\n转发请求到 FastCGI 服务（如 PHP-FPM）  \n\n```nginx\nlocation ~ \\.php$ {\n    fastcgi_pass unix:/var/run/php-fpm.sock;\n    include fastcgi_params;\n}\n```\n\n---\n\n### 8. `uwsgi_pass`（Python uWSGI 转发）\n\n转发到 uWSGI 服务  \n\n```nginx\nlocation /python {\n    uwsgi_pass 127.0.0.1:9001;\n    include uwsgi_params;\n}\n```\n\n---\n\n### 9. `memcached_pass`（Memcached 转发）\n\n直接查询 Memcached  \n\n```nginx\nlocation @memcached {\n    memcached_pass memcached_backend;\n    memcached_key $uri;\n}\n```\n\n## 高级使用技巧\n\n### 1. 嵌套 location\n\n```nginx\nlocation / {\n    # 父级处理\n    location ~* \\.(gif|jpg)$ {\n        # 子级处理图片\n    }\n}\n```\n\n### 2. 命名 location (@)\n\n```nginx\nlocation / {\n    try_files $uri @fallback;  # 命名定位点\n}\n\nlocation @fallback {\n    proxy_pass http://rescue_server;\n}\n```\n\n### 3. 变量动态路由\n\n```nginx\nlocation ~ ^/user/(?<user_id>\\d+) {\n    proxy_pass http://user_api/$user_id;\n}\n```\n\n### 4. 多条件匹配\n\n```nginx\nlocation / {\n    # 同时满足条件才匹配\n    if ($http_user_agent ~* \"mobile\") {\n        root /mobile-site;\n    }\n}\n```\n\n### **常见陷阱**：\n\n- `proxy_pass` 结尾 `/` 差异：\n\n  ```nginx\n  location /api/ {\n      proxy_pass http://backend/;  # /api/user → /user \n      proxy_pass http://backend;   # /api/user → /api/user\n  }\n  ```\n\n- `root` vs `alias` 区别：\n\n  ```nginx\n  location /img/ {\n      root /data;     # /img/cat.jpg → /data/img/cat.jpg\n      alias /images/; # /img/cat.jpg → /images/cat.jpg\n  }\n  ```\n\n","categoryId":12,"viewCount":1201,"categoryName":"Nginx","author":"球接子","authorAvatar":null,"tagIds":[13,14],"tagNames":["Nginx","中间件"]}}