Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> 電腦軟體教學 >> 伺服器技術 >> 關於伺服器

Nginx 靜態資源 (CSS/JS/圖片) 404 問題根因與 location 配置最佳實踐

編輯:關於伺服器

Nginx 作為靜態資源服務器或反向代理時,CSS/JS/圖片返回 404 是最常見的配置錯誤。核心原因在於 **location 匹配優先級** 與 **root/alias 指令用法** 的誤解。本文系統講解 Nginx 處理靜態文件的正確配置模式,解決路徑映射錯誤、優先級衝突、緩存優化等問題。

核心誤區:root vs alias

指令路徑拼接邏輯適用場景
root請求 URI **完整拼接** 到 root 路徑後
location /static/ { root /data; }
請求 /static/style.css → /data/static/style.css
目錄結構與 URI 保持一致
alias請求 URI **替換 location 前綴** 後拼接
location /static/ { alias /data/assets/; }
請求 /static/style.css → /data/assets/style.css
URI 與實際目錄結構不一致

鐵律:alias **必須**以 / 結尾;location 使用正則時**不能用 alias** (僅支援 root)。

location 匹配優先級 (決定生死)

優先級從高到低:
1. = 精確匹配           location = /logo.png { ... }
2. ^~ 前綴匹配 (不再正則) location ^~ /static/ { ... }
3. ~ / ~* 正則匹配       location ~ \.(css|js|png)$ { ... }
4. / 通用前綴匹配        location / { ... }

陷阱:正則 location (~) 優先級**高於**普通前綴 location。若配置:

location / { proxy_pass https://backend; }  # 所有請求代理到後端
location ~ \.(css|js)$ { root /data/static; }  # 靜態文件正則

請求 /style.css 會匹配正則 location,**正常返回靜態文件**。但請求 /api/user.css (動態生成的 CSS) 也會被正則攔截,**錯誤返回 404**。

最佳實踐配置模板

server {
    listen 80;
    server_name example.com;
    root /data/www/example.com;  # 全局 root, 所有 location 繼承

    # 1. 優先處理靜態資源 (前綴匹配 ^~, 避免正則陷阱)
    location ^~ /static/ {
        # 實際路徑: /data/www/example.com/static/
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
        try_files $uri =404;  # 明確 404, 不落入後端
    }

    location ^~ /uploads/ {
        # 用戶上傳文件, 禁用 PHP 執行 (安全)
        location ~ \.php$ { deny all; }
        expires 7d;
        add_header Cache-Control "public";
    }

    # 2. 特定文件類型正則 (僅作為兜底, 不作為主要入口)
    location ~* \.(jpg|jpeg|png|gif|ico|webp|css|js|woff|woff2|ttf|svg|mp4|webm)$ {
        # 僅匹配未被上方 ^~ 捕獲的請求
        expires 30d;
        add_header Cache-Control "public";
        access_log off;
        try_files $uri =404;
    }

    # 3. 動態請求代理到 PHP-FPM
    location / {
        try_files $uri $uri/ /index.php?$query_string;  # Laravel/ThinkPHP 路由支援
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_intercept_errors on;
    }

    # 4. 禁用隱藏文件訪問
    location ~ /\. { deny all; access_log off; log_not_found off; }
}

常見場景專項解決方案

場景一:前端構建產物部署在子目錄 (如 /app/dist/)

location ^~ /app/ {
    alias /data/www/example.com/dist/;  # 注意 alias 尾部 /
    try_files $uri $uri/ /app/index.html;  # SPA 歷史模式回退
    expires 1h;  # HTML 不長期緩存
}

場景二:多項目共用域名,不同路徑指向不同根目錄

location ^~ /project1/ {
    alias /data/www/project1/;
    try_files $uri $uri/ /project1/index.html;
}
location ^~ /project2/ {
    alias /data/www/project2/;
    try_files $uri $uri/ /project2/index.php?$query_string;
}

場景三:圖片防盜鏈

location ~* \.(jpg|png|gif)$ {
    valid_referers none blocked example.com *.example.com;
    if ($invalid_referer) {
        return 403;  # 或 rewrite 到默認圖片
    }
    expires 30d;
}

調試技巧:看懂 Nginx 怎麼匹配

# 開啟調試日誌 (需 nginx 編譯時 --with-debug)
error_log /var/log/nginx/debug.log debug;

# 或使用 ngx_lua 打印匹配信息
location / {
    default_type text/plain;
    echo "location: $uri";
    echo "document_root: $document_root";
    echo "request_filename: $request_filename";
}

總結檢查清單

  • [ ] 靜態資源 location 使用 ^~ 前綴匹配,避免正則優先級陷阱。
  • [ ] root 用於目錄結構一致,alias 用於目錄重映射 (注意尾部 /)。
  • [ ] try_files $uri =404 明確靜態文件不存在時返回 404,不落入動態後端。
  • [ ] 上傳目錄嵌套 location ~ \.php$ { deny all; } 防止腳本執行。
  • [ ] 配置 expires + Cache-Control 減少重複請求。

遵循「前綴優先、root/alias 分明、try_files 兜底、安全隔離」原則,可徹底解決 Nginx 靜態資源 404 難題。

Copyright © Windows教程網 All Rights Reserved