リクエストされたURLのパスに応じて処理を分岐(locationコンテキスト)

広告

location コンテキストは、リクエストされた URL のパスに応じて処理を分岐するための設定です。パスごとに異なるファイルを返したり、リダイレクトやアクセス制限を行うことができます。ここでは Nginx における location コンテキストの使い方について解説します。

locationコンテキストとは

仮想サーバ(serverコンテキスト)の中に記述する location コンテキストは、リクエストされた URL のパスに応じて処理内容を振り分けるための設定です。 location コンテキストの書式は次の通りです。

Syntax:   location uri { ... }
Default:  —
Context:  server, location

location コンテキストは server コンテキストに記述します。また location コンテキスト内に記述することもできます。

location に記述された URL のパスでリクエストに含まれる URL のパスと照合し、指定された条件(前方一致や完全一致)に一致した場合に処理が振り分けられます。

http {
  server {
    location URLのパスA {
      # ・・・
    }

    location URLのパスB {
      # ・・・
    }
  }
}

リクエストの URL は例えば次のようなものです。

http://www.example.com/doc/index.htm?page=2

location で調べるパスの部分というのは、ホスト(www.example.com)の後のパス部分です。ただし ?# より後の部分はクエリやフラグメントなのでパスには含みません。

http://www.example.com/doc/index.htm?page=2

例えば location の URL のパスに / を記述した場合、リクエストに含まれる URL のパスは必ず / から始まるので、すべてのリクエストがこの location に振り分けられます。

http {
  server {
    location / {
      # ・・・
    }
  }
}

また location の URL のパスに //images/ を記述したものをそれぞれ用意した場合、リクエストに含まれる URL のパスが /images/ で始まる場合はあとの location に振り分けられ、それ以外のリクエストは最初の location に振り分けられます。

http {
  server {
    location / {
      # ・・・
    }

    location /images/ {
      # ・・・
    }
  }
}

※ リクエストに含まれる URL のパスが /images/ で始まる場合も / と一致しますが、複数の location が一致する場合は、優先順位によって最も適合する 1 つだけが適用されます。基本的には「より長く一致するパス」が優先されますが、詳細なルールについては後述します。

location コンテキストのブロックでは、リクエストに応じてどのファイルを返すかや、アクセス制御、別のサーバへ転送するかなどの処理を記述します。代表的なディレクティブとしては、 rootaliasrewriteallow などがあります。

http {
  server {
    location / {
      root  /www/html;
      index  index.html index.htm;
    }

    location /images/ {
      alias /data/images/;
    }
  }
}

マッチ方法を指定する

location は明示的に指定しなかった場合、 location に記述された URL のパスがリクエストに含まれる URL のパスと前方一致するかどうかを調べますが、修飾子を指定することでマッチ方法を別の方式にすることができます。書式は次の通りです。

location [ = | ~ | ~* | ^~ ] uri { ... }

指定できる修飾子は 4 つ(=, ~, ~*, ^~)あり、それぞれ次のような意味があります。

=   完全一致
~   正規表現(大文字小文字区別あり)
~*  正規表現(大文字小文字区別なし)
^~  前方一致

修飾子の ^~ は、修飾子を省略した場合と同じ前方一致ですが、省略した場合と ^~ を明示的に指定した場合では優先順位が異なりますのでご注意ください(のちほど解説します)。

完全一致の = を指定した場合は、 location で指定した URL のパスと、リクエストに含まれる URL のパスが完全に一致した場合にのみマッチします。次の例を見てください。

http {
  server {
    location = / {
      # ・・・
    }

    location / {
      # ・・・
    }
  }
}

リクエストの URL のパスが /hello.html だった場合、 2 番目の location とは一致しますが、 1 番目の location とは完全に一致しないためマッチしません。 1 番目とマッチするのはリクエストの URL のパスが / だった場合だけです。

location の URL のパスを正規表現で指定する場合、修飾子に ~ または ~* を指定します。次の例を見てください。

http {
  server {
    location ~* \.(png|jpg)$ {
      # ・・・
    }
  }
}

リクエストの URL のパスの末尾が .png または .jpg だった場合にマッチします。(大文字と小文字を区別しないので .PNG などでもマッチします)。

locationの優先順位

リクエストの URL のパスが、複数の location と一致する場合、次の優先順位でいずれかが選択されます。

1. =(完全一致)
2. ^~(前方一致)
3. 正規表現(~ / ~*)
4. 省略した場合の前方一致

選択は次のように行われます。

まず最初にすべての location を対象に、リクエストに含まれる URL のパスと前方一致または完全一致するかどうかを調べます。

完全一致しており、かつ修飾子が = だった場合はその location が選択され、これ以上評価されません。

前方一致した場合(完全一致も含む)に、修飾子が ^~ だった場合はその location が選択され、これ以上評価されません。(複数の location が同じ条件で一致した場合は、最も長く一致したものが選択されます)。

前方一致した場合に、修飾子が省略されていた場合はその location が一旦選択されます。このあと正規表現で一致するかどうかを続けて調べます。(複数の location が同じ条件で一致した場合は、最も長く一致したものが選択されます)。

次に location に記述された値を正規表現として、リクエストに含まれる URL のパスと一致するかどうかを調べます。

正規表現に一致した場合はその location が選択され、これ以上評価されません。(複数の location が同じ条件で一致した場合は、上に記述されているもの選択されます)。

正規表現に一致するものがなかった場合、前方一致して修飾子が省略されていた location の選択が確定します。

注意する点として、前方一致の場合はより長く一致したものが選択されるのに対して、正規表現で一致した場合はより上に書かれているものが選択される点です。

次のような location / はすべてのリクエストと前方一致しますが、URL のパスが最も短いため、他により長く一致する location がある場合はそちらが優先されます。そのため、他の location と一致しなかったリクエストに対して適用されることが多く、結果として共通の処理を記述するための location として利用されます。

http {
  server {
    location / {
      # ・・・
    }
  }
}

補足:URIとURNの違いについて

URL と URI の違いについて簡単に説明します。URI はインターネット上のリソース(ファイルやデータなど)を識別するための総称(上位概念)で、URL はその「場所」を示すものです。なお、名前を表す識別子として URN もあります。

場所(URL)も名前(URN)も識別子の一種であるため、URI は URL よりも広い概念といえます。厳密には異なりますが、Nginx の設定に関する範囲では、どちらも「リクエストされたアドレス」を指すものとして扱われることが多く、同じように理解しても差し支えありません。

URIとURNの違いについて(1)

-- --

Nginx における location コンテキストの使い方について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。