😵
Nuxt3 on Nginx構成でtrailing slash強制リダイレクトを防ぐ方法
はじめに
Nuxt3 on Nginx構成でフロントエンド開発をしていた際、
/login
など末尾にスラッシュを付けずにアクセスしたとき 301 リダイレクト で /login/
に書き換わってしまい、検証環境デプロイ時に不具合が発生しました。
この解決に困ったので、書き残したいと思います。
この記事でわかること
- 末尾スラッシュが強制される Nginx の仕組み
- 問題の設定箇所の特定方法
-
try_files
を使ったリダイレクト回避パターン
症状
$ curl -I http://localhost:3000/login
HTTP/1.1 301 Moved Permanently
Location: http://localhost:3000/login/
/login/
へ 301 で飛ばされる。
index
ディレクティブ
原因は location / {
root /usr/share/nginx/html;
index index.html index.htm; # ← これがトリガー
}
-
/login
にリクエストが来る - 実パス
/usr/share/nginx/html/login/
がディレクトリとして存在 -
index.html
が見つかる - Nginx は「ディレクトリ=末尾
/
必須」と判断し 301 リダイレクト
リライトルールが無くても、index
を指定しているだけで起こる Nginx の標準動作 です。
try_files
に置き換える
解決策: もっとも簡単なのは index
を外し、try_files
で「ファイル or ファイルが無ければそのディレクトリの index.html
」を探すようにすることです。
location / {
root /usr/share/nginx/html;
try_files $uri $uri/index.html =404;
}
-
$uri
… リクエストそのもの (/login
) -
$uri/index.html
… ディレクトリ配下のindex.html
-
=404
… どちらも無ければ 404 を返す(リダイレクトしない)
手順まとめ
-
location /
ブロックのindex
行を削除 -
代わりに
try_files
を追加 -
設定をテストしてリロード
sudo nginx -t # 構文チェック sudo nginx -s reload
-
curl -I http://localhost:3000/login
で 301 が消えたことを確認
おわりに
Nginx の「ディレクトリには末尾 /
」というお作法は知らないとハマりがちです。
try_files
を使えば URL を変えずに静的ファイルをスマートに配信できます。ぜひ試してみてください。
Discussion