😵
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