Cấu hình máy chủ HTTP trong Nginx – Các khối location

Trong bài viết này, chúng ta sẽ tìm hiểu đến thành phần cuối cùng được sử dụng trong việc cấu hình máy chủ HTTP trong Nginx, đó là các khối location.

Nginx cung cấp cho chúng ta khả năng tinh chỉnh cấu hình xuống 3 cấp – tại cấp giao thức (khối http), cấp máy chủ (khối server) và cấp URI (khối location).

Các từ bổ nghĩa cho các khối Location

Nginx cho phép chúng ta định nghĩa các khối location bằng việc chỉ rõ 1 khuôn mẫu URI sẽ được dùng để đối chiếu với URI của yêu cầu.

server {
server_name website.com;
location /admin/ {
# The configuration you place here only applies to http://website.com/admin/
}
}

Thay vì sử dụng 1 tên thư mục đơn giản, chúng ta có thể sử dụng những khuôn mẫu phức tạp như:

location [=|~|~*|^~|@] pattern {…}

Các ký hiệu =|~|~*|^~|@ trong ví dụ trên được gọi là bộ bổ nghĩa cho location, chúng định nghĩa cách Nginx đối chiếu 1 mẫu cụ thể với URI.

Bổ từ =

URI phải khớp chính xác với khuôn mẫu được chỉ định. Khuôn mẫu ở đây được giới hạn là chuỗi ký tự bình thường, không được sử dụng biểu thức chính quy.

server {
server_name website.com;
location = /abcd {
}
}

Trong ví dụ trên:

  • Áp dụng cho http://website.com/abcd (trùng khớp)
  • Áp dụng cho http://website.com/ABCD (phân biệt chữ hoa nếu như hệ điều hành của chúng ta sử dụng filesystem có phân biệt chữ hoa)
  • Áp dụng cho http://website.com/abcd?param1&param2 (không quan tâm các đối số truy vấn)
  • Không áp dụng cho http://website.com/abcd/ (dư ký hiệu /)
  • Không áp dụng cho http://website.com/abcde

Trường hợp không sử dụng bổ từ

URI phải bắt đầu với 1 mẫu được chỉ định. Chúng ta không thể sử dụng biểu thức chính quy:

server {
server_name website.com;
location /abcd {
}
}

Trong ví dụ trên:

  • Áp dụng cho http://website.com/abcd (trùng khớp)
  • Áp dụng cho http://website.com/ABCD (nếu hệ điều hành không phân biệt chữ hoa, chữ thường)
  • Áp dụng cho http://website.com/abcd?param1&param2 (không quan tâm đối số chuỗi truy vấn)
  • Áp dụng cho http://website.com/abcd/ (bắt đầu với abcd)
  • Áp dụng cho http://website.com/abcde (bắt đầu với abcd)

Bổ từ ~

URI được yêu cầu phải khớp (phân biệt chữ hoa, chữ thường) với biểu thức chính quy được chỉ rõ:

server {
server_name website.com;
location ~ ^/abcd$ {
}
}

Biểu thức chính quy ^/abcd$ => 1 mẫu phải bắt đầu với /, theo sau là abc, và kết thúc là d.

Ví dụ trên:

  • Áp dụng cho http://website.com/abcd (trùng khớp)
  • Không áp dụng cho http://website.com/ABCD (chữ hoa)
  • Áp dụng cho http://website.com/abcd?param1&param2 (không quan tâm đến các đối số trong URI)
  • Không áp dụng cho http://website.com/abcd/ (ký hiệu / không khớp với biểu thức chính quy)
  • Không áp dụng cho http://website.com/abcde (thừa ký tự e)

Lưu ý:

Với những hệ điều hành như Microsoft Windows, ~ và ~* không phân biệt chữ hoa, chữ thường, vì hệ điều hành này sử dụng filesystem không phân biệt chữ hoa, chữ thường.

Bổ từ ~*

URI được yêu cầu phải khớp (không phân biệt chữ hoa, chữ thường) với 1 biểu thức chính quy được chỉ rõ.

server {
server_name website.com;
location ~* ^/abcd$ {
...
}
}

Trong ví dụ trên:

  • Áp dụng cho http://website.com/abcd (trùng khớp)
  • Áp dụng cho http://website.com/ABCD (không phân biệt chữ hoa)
  • Áp dụng cho http://website.com/abcd?param1&param2 (không quan tâm đối số trong chuỗi truy vấn)
  • Không áp dụng cho http://website.com/abcd/ (dư ký hiệu /)
  • Không áp dụng cho http://website.com/abcde (dư ký tự e)

Bổ từ ^~

Tương tự với trường hợp không dùng bổ từ, URI phải bắt đầu với 1 mẫu cụ thể. Sự khác nhau là nếu mẫu đó khớp, Nginx ngừng tìm kiếm các mẫu khác.

Bổ từ @

Định nghĩa 1 khối location được đặt tên. Khách hàng không thể truy cập những khối này, chúng chỉ có thể truy cập bởi các truy cập nội bộ được tạo ra bởi các chỉ thị khác, như là try_files hoặc error_page.

Thứ tự và độ ưu tiên khi tìm kiếm các khối location

Ví dụ:

server {
server_name website.com;
location /files/ {
# applies to any request starting with "/files"
# for example /files/doc.txt, /files/, /files/temp/
}
location = /files/ {
# applies to the exact request to "/files/"
# and as such does not apply to /files/doc.txt
# but only /files/
}
}

Khi khách hàng truy cập http://website.com/files/doc.txt, khối location đầu tiên được sử dụng. Tuy nhiên, khi họ truy cập http://website.com/files/, khối location thứ 2 được sử dụng (mặc dù khối 1 cũng khớp) do nó có ưu tiên cao hơn khối thứ 1.

Thứ tự chúng ta đặt các khối location trong tập tin cấu hình không liên quan đến độ ưu tiên này. Nginx sẽ tìm các mẫu khớp theo 1 thứ tự cụ thể:

  1. Các khối location với bổ từ =: nếu chuỗi được chỉ rõ trùng khớp với URI, Nginx giữ lại khối location này.
  2. Các khối location không sử dụng bổ từ: nếu chuỗi được chỉ rõ trùng khớp với URI, Nginx giữ lại khối location này.
  3. Các khối location sử dụng bổ từ ^~: Nếu chuỗi chỉ rõ khớp với phần đầu của URI, Nginx giữ lại khối location này.
  4. Các khối location sử dụng bổ từ ~ hoặc ~*: Nếu biểu thức chính quy khớp với URI, Nginx giữ lại khối location này.
  5. Các khối location không sử dụng bổ từ: Nếu chuỗi được chỉ rõ khớp với phần đầu của URI, Nginx giữ lại khối location này.

Chúng ta cùng xem qua 3 ví dụ sau để làm rõ vấn đề này:

Ví dụ 1:

server {
server_name website.com;
# Block 1
location /doc {
 [...] # requests beginning with "/doc"
}
# Block 2
location ~* ^/document$ {
[...] # requests exactly matching "/document"
}
}

Khi khách hàng truy cập http://website.com/document

  • Block 1 (URI bắt đầu với /doc) => có thứ tự ưu tiên là 5.
  • Block 2 (URI khớp với biểu thức chính quy ^/document$) => có thứ tự ưu tiên là 4.

=> Trong trường hợp này, Nginx sử dụng khối location thứ 2 cho truy cập trên.

Ví dụ 2:

server {
server_name website.com;
# Block 1
location /document {
[...] # requests beginning with "/document"
}
# Block 2
location ~* ^/document$ {
[...] # requests exactly matching "/document"
}
}

Khách hàng truy cập http://website.com/document

  • Block 1 (chuỗi được chỉ định trùng khớp với URI) => thứ tự ưu tiên là 2.
  • Block 2 (URI khớp với biểu thức chính quy) => thứ tự ưu tiên là 4.

=> Trong trường hợp này, Nginx sử dụng khối thứ 1 cho truy cập trên.

Ví dụ 3:

server {
server_name website.com;
# Block 1
location ^~ /doc {
[...] # requests beginning with "/doc"
}
# Block 2
location ~* ^/document$ {
[...] # requests exactly matching "/document"
}
}

Khách hàng truy cập http://website.com/document

  • Block 1 (chuỗi khớp với phần đầu của URI) => thứ tự ưu tiên là 3.
  • Block 2 (biểu thức chính quy khớp với URI) => thứ tự ưu tiên là 4.

=> Trong trường hợp này, Nginx sử dụng khối thứ 1.

Chúng ta hoàn tất bài tìm hiểu về thành phần cấu hình cuối cùng trong module HTTP Core của Nginx tại đây.

Xin cám ơn các bạn đã quan tâm theo dõi.