Nginx location靜態(tài)文件映射配置過程
遇到問題?
以下這個Nginx的配置,愿意為訪問https://abc.com會指向一個動態(tài)網(wǎng)站,訪問https://abc.com/tongsongzj時會訪問靜態(tài)網(wǎng)站,但是配置之后(注意看后面那個location /tongsongzj/靜態(tài)文件映射的配置),此時不能通過https://abc.com/tongsongzj/index.html正確訪問,顯示報錯信息如下:

問:這是為啥?需要如何修改?
已經(jīng)確認(rèn)前端代碼在宿主機路徑/opt/docker-data/nginx/h5下,且對應(yīng)的docker中nginx容器真實路徑為/usr/share/nginx/h5。
Nginx配置如下
# ABC官網(wǎng)Nginx配置
# 這里跳轉(zhuǎn)到動態(tài)網(wǎng)站
server {
listen 80; # 監(jiān)聽80端口,用于HTTP請求
# listen 443 ssl; # 監(jiān)聽443端口,用于HTTPS請求,并啟用SSL
listen 443 ssl http2; # 啟用 HTTP/2 的 HTTPS 監(jiān)聽
server_name www.abc.com abc.com; # 綁定的域名
root html;
index index.html index.htm;
# SSL證書和私鑰的路徑
ssl_certificate conf.d/cert/abc.pem;
ssl_certificate_key conf.d/cert/abc.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
#表示使用的加密套件的類型。
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; #表示使用的TLS協(xié)議的類型。
ssl_prefer_server_ciphers on;
location / {
#root html; #Web網(wǎng)站程序存放目錄。
#index index.html index.htm;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://abc-cms:9999;
# proxy_pass http://172.19.19.80:8082;
}
# 靜態(tài)頁面配置,代碼傳到/opt/docker-data/nginx/h5路徑即可
location /tongsongzj/ {
# 靜態(tài)網(wǎng)頁配置
root /usr/share/nginx/h5; # 靜態(tài)網(wǎng)頁的根目錄
index index.html; # 默認(rèn)打開的文件
try_files $uri $uri/ /index.html; # 嘗試查找URI對應(yīng)的文件,否則返回index.html
# 禁用緩存
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
}
問題解決
靜態(tài)文件無法訪問的原因在于路徑拼接方式錯誤。
以下是詳細(xì)分析和解決方案:
問題分析:路徑拼接邏輯錯誤
當(dāng)前配置中使用了 root 指令:
location /tongsongzj/ {
root /usr/share/nginx/h5; # 最終路徑 = root + location
...
}
Nginx 會將 location 路徑拼接到 root 后面,因此實際訪問路徑為:
/usr/share/nginx/h5/tongsongzj/index.html
但根據(jù)你的描述,靜態(tài)文件直接存放在容器的 /usr/share/nginx/h5 路徑下(對應(yīng)宿主機 /opt/docker-data/nginx/h5),并未創(chuàng)建 tongsongzj 子目錄,導(dǎo)致路徑不匹配。
解決方案:改用 alias 指令
將 root 改為 alias 指令,并直接指向靜態(tài)文件的實際路徑:
location /tongsongzj/ {
alias /usr/share/nginx/h5/; # 直接映射路徑,不拼接 location
index index.html;
try_files $uri $uri/ /tongsongzj/index.html; # 修正回退路徑
# 禁用緩存配置
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
關(guān)鍵修改說明:
alias會直接將/tongsongzj/映射到容器內(nèi)的/usr/share/nginx/h5/目錄,不再拼接location路徑。- 修正
try_files確?;赝说?/tongsongzj/index.html,避免路徑錯誤。
其他注意事項
1.確認(rèn)文件路徑:
確保容器內(nèi) /usr/share/nginx/h5 路徑下直接存在 index.html 等靜態(tài)文件,而不是嵌套在子目錄中。
2.檢查目錄權(quán)限:
運行以下命令確保 Nginx 有權(quán)限訪問該目錄:
docker exec [nginx容器名] ls -l /usr/share/nginx/h5
如果權(quán)限不足,嘗試在宿主機執(zhí)行:
chmod -R 755 /opt/docker-data/nginx/h5
3.檢查 Nginx 日志:
查看錯誤日志定位具體原因:
docker logs [nginx容器名] 2>&1 | grep -i error
完整修正配置參考
# 靜態(tài)頁面配置
location /tongsongzj/ {
alias /usr/share/nginx/h5/; # 使用 alias 直接映射真實路徑
index index.html;
try_files $uri $uri/ /tongsongzj/index.html; # 保持前端路由正常
# 禁用緩存
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
或者
# 靜態(tài)頁面配置,代碼傳到 /opt/docker-data/nginx/h5/tongsongzj 路徑即可
# 說明:使用root指令,Nginx 會將 location 路徑拼接到 root 后面,因此實際訪問路徑為:/usr/share/nginx/h5/tongsongzj/index.html
location /tongsongzj/ {
# 靜態(tài)網(wǎng)頁配置
root /usr/share/nginx/h5; # 靜態(tài)網(wǎng)頁的根目錄 【最終路徑 = root + location】
index index.html; # 默認(rèn)打開的文件
try_files $uri $uri/ /index.html; # 嘗試查找URI對應(yīng)的文件,否則返回index.html
# 禁用緩存
expires off;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}
修改后重啟 Nginx 服務(wù)即可生效:
docker exec [nginx容器名] nginx -s reload
root和alias的核心區(qū)別
Nginx 的 root 和 alias 指令都用于定義靜態(tài)文件的路徑映射,但它們的路徑拼接邏輯完全不同。理解它們的區(qū)別是避免配置錯誤的關(guān)鍵。
1.root指令
定義
- 路徑拼接邏輯:
root會將location的 URI 路徑拼接到root指定的路徑后面。 - 適用場景:當(dāng) URI 路徑和文件系統(tǒng)的目錄結(jié)構(gòu)完全一致時(例如
/static/對應(yīng)/var/www/static/)。
示例
location /static/ {
root /var/www;
}
當(dāng)訪問 /static/image.jpg 時,Nginx 會查找文件:
/var/www/static/image.jpg
(路徑 = root + location 的 URI)
優(yōu)點
- 簡單直觀:URI 路徑和文件路徑一一對應(yīng),適合標(biāo)準(zhǔn)目錄結(jié)構(gòu)。
- 自動處理子路徑:支持嵌套路徑(如
/static/css/style.css)。
缺點
- 路徑強制拼接:無法靈活映射到與 URI 不匹配的目錄結(jié)構(gòu)。
- 冗余路徑:如果 URI 路徑和實際目錄結(jié)構(gòu)不匹配,會導(dǎo)致路徑錯誤。
注意事項
- 確保
root路徑的末尾沒有斜杠(例如/var/www,而不是/var/www/)。 - 如果
location路徑是/static/,實際文件必須存放在root路徑下的static子目錄中。
2.alias指令
定義
- 路徑拼接邏輯:
alias會用指定的路徑完全替換location的 URI 路徑。 - 適用場景:當(dāng) URI 路徑和實際文件路徑不一致時(例如將
/docs/映射到/usr/share/nginx/html)。
示例
location /docs/ {
alias /usr/share/nginx/html/;
}
當(dāng)訪問 /docs/readme.html 時,Nginx 會查找文件:
/usr/share/nginx/html/readme.html
(路徑 = alias 路徑 + URI 去除 location 前綴后的部分)
優(yōu)點
- 靈活映射:可以自由將 URI 映射到任意目錄結(jié)構(gòu)。
- 無冗余路徑:URI 路徑和文件路徑完全解耦。
缺點
- 路徑易錯:必須嚴(yán)格處理斜杠(
/),否則會導(dǎo)致路徑拼接錯誤。 - 不支持自動子路徑:需要手動處理嵌套路徑。
注意事項
alias路徑的末尾必須帶斜杠(例如/usr/share/nginx/html/)。location的路徑末尾必須帶斜杠(例如/docs/而不是/docs),否則路徑替換可能不完整。
關(guān)鍵對比表格
| 特性 | root | alias |
|---|---|---|
| 路徑拼接邏輯 | root + location URI | 用 alias 完全替換 location URI |
| 斜杠處理 | root 路徑末尾不帶斜杠 | alias 路徑末尾必須帶斜杠 |
| 適用場景 | URI 與文件路徑一致 | URI 與文件路徑不一致 |
| 嵌套路徑支持 | 自動支持(如 /static/css/) | 需手動處理(依賴 try_files) |
| 常見錯誤 | 文件路徑多了一層子目錄 | 路徑拼接錯誤(斜杠問題) |
常見錯誤場景與修復(fù)
錯誤 1:路徑多了一層子目錄
錯誤配置(使用 root):
location /tongsongzj/ {
root /usr/share/nginx/h5;
index index.html;
}
- 預(yù)期路徑:
/usr/share/nginx/h5/index.html - 實際路徑:
/usr/share/nginx/h5/tongsongzj/index.html(多了一層tongsongzj)
修復(fù)方法:改用 alias:
location /tongsongzj/ {
alias /usr/share/nginx/h5/; # 注意末尾斜杠
index index.html;
}
錯誤 2:斜杠缺失導(dǎo)致路徑拼接錯誤
錯誤配置:
location /docs {
alias /usr/share/nginx/html; # 缺少末尾斜杠
}
- 訪問
/docs/readme.html時,路徑變?yōu)?/usr/share/nginx/htmlreadme.html(斜杠缺失導(dǎo)致拼接錯誤)。
修復(fù)方法:
location /docs/ { # location 末尾加斜杠
alias /usr/share/nginx/html/; # alias 末尾加斜杠
}
最佳實踐
1.優(yōu)先使用 root:
- 如果 URI 路徑和文件目錄結(jié)構(gòu)完全一致(例如
/static/對應(yīng)/var/www/static/),使用root更簡單。
2.必須用 alias 的場景:
- 當(dāng)需要將 URI 映射到一個與 URI 路徑不匹配的目錄時(例如將
/legacy/映射到/old-site/)。
3.嚴(yán)格處理斜杠:
location和alias的路徑末尾必須同時帶斜杠或不帶斜杠,且邏輯一致。- 推薦統(tǒng)一在
location和alias路徑末尾加斜杠。
4.結(jié)合 try_files 處理前端路由:
- 如果是單頁應(yīng)用(如 Vue/React),需配置
try_files回退到入口文件:
location /tongsongzj/ {
alias /usr/share/nginx/h5/;
try_files $uri $uri/ /tongsongzj/index.html; # 回退到 index.html
}
5.檢查文件權(quán)限:
確保 Nginx 進(jìn)程有權(quán)限讀取目錄和文件:
chmod -R 755 /opt/docker-data/nginx/h5 # 宿主機路徑
總結(jié)
root:路徑拼接簡單,適合標(biāo)準(zhǔn)目錄結(jié)構(gòu)。alias:路徑替換靈活,適合自定義映射。
核心區(qū)別在于路徑拼接邏輯,務(wù)必通過實際文件路徑驗證配置。
配置完成后,使用 nginx -t 測試語法,并通過日志排查錯誤:
tail -f /var/log/nginx/error.log
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx使用mirror指令實現(xiàn)接口復(fù)制
Nginx中使用mirro指令可以方便地實現(xiàn)接口請求的復(fù)制,這個功能非常適合用于流量監(jiān)控、數(shù)據(jù)收集或負(fù)載均衡,下面我們就來看看具體的用法吧2024-10-10
nginx快速部署一個網(wǎng)站服務(wù)(多域名+多端口)
本文主要介紹了nginx快速部署一個網(wǎng)站服務(wù),并實現(xiàn)多域名和多端口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10
Nginx根據(jù)不同瀏覽器語言配置頁面跳轉(zhuǎn)的方法
這篇文章主要介紹了Nginx根據(jù)不同瀏覽器語言配置頁面跳轉(zhuǎn)的方法,包括一個簡體繁體的基本判斷方法及實際根據(jù)中英文跳轉(zhuǎn)的例子,需要的朋友可以參考下2016-04-04
Nginx正向代理實現(xiàn)局域網(wǎng)電腦訪問外網(wǎng)的過程詳解
在工作中我遇到了一個類似的情況:在公司網(wǎng)絡(luò)中,由于管理要求,局域網(wǎng)內(nèi)的電腦不能直接訪問外網(wǎng),但是,工作上領(lǐng)導(dǎo)吩咐需要讓局域網(wǎng)內(nèi)的電腦能夠訪問外網(wǎng)上的某個網(wǎng)站,這時候就需要用到正向代理,本文將介紹如何配置 Nginx 實現(xiàn)這一功能,需要的朋友可以參考下2024-03-03
nginx could not build the server_names_hash 解決方法
服務(wù)器名字的hash表是由指令 server_names_hash_max_size 和 server_names_hash_bucket_size所控制的。2011-03-03

