Introduction
Nginx là một trong những web server phổ biến nhất trên thế giới. Nó có thể làm tốt nhiệm vụ handle cho hệ thống có lượng truy cập lớn cùng 1 thời điểm, có thể đảm nhận nhiều công việc như: webserver, mail server hay một reserve proxy server. Như ở tiêu đề, trong bài viết này chúng ta sẽ tìm hiểu về Khối location và các modifiers đi kèm.
Nếu bạn muốn có cái nhìn tổng quan về nginx và về khối location, có thể đọc bài viết sau: Nginx Cơ bản, Cấu hình location
Khối location
Cấu trúc chung file config của nginx:
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
).
Bây giờ, chúng ta sẽ bắt tay vào 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 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. Ví dụ :
server {
server_name abc.com;
location /admin/ {
#Cấu hình đặt ở đây chỉ áp dụng cho đường dẫn http://abc.com/admin/
}
}
Tuy nhiên, 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.
1. Modifier =
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 abc.com;
location = /abcd {
}
}
Ví dụ trên, ta sẽ có kết quả sau :
- Áp dụng cho http://abc.com/abcd (trùng khớp)
- Áp dụng cho http://abc.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://abc.com/abcd?param1¶m2 (không quan tâm các đối số truy vấn)
- Không áp dụng cho http://abc.com/abcd/ (dư ký hiệu /)
- Không áp dụng cho http://abc.com/abcde (dư ký tự e)
2. Trường hợp không sử dụng modifier
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 abc.com;
location /abcd {
}
}
Ví dụ trên, ta sẽ có kết quả sau :
- Áp dụng cho http://abc.com/abcd (trùng khớp)
- Áp dụng cho http://abc.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://abc.com/abcd?param1¶m2 (không quan tâm đối số chuỗi truy vấn)
- Áp dụng cho http://abc.com/abcd/ (bắt đầu với abcd)
- Áp dụng cho http://abc.com/abcde (bắt đầu với abcd)
3. Modifier ~
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 abc.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, ta sẽ có kết quả sau :
- Áp dụng cho http://abc.com/abcd (trùng khớp)
- Không áp dụng cho http://abc.com/ABCD (chữ hoa)
- Áp dụng cho http://abc.com/abcd?param1¶m2 (không quan tâm đến các đối số trong URI)
- Không áp dụng cho http://abc.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://abc.com/abcde (thừa ký tự e)
NOTE
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.
4. Modifier ~*
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 abc.com;
location ~* ^/abcd$ {
...
}
}
Ví dụ trên, ta sẽ có kết quả sau :
- Áp dụng cho http://abc.com/abcd (trùng khớp)
- Áp dụng cho http://abc.com/ABCD (không phân biệt chữ hoa)
- Áp dụng cho http://abc.com/abcd?param1¶m2 (không quan tâm đối số trong chuỗi truy vấn)
- Không áp dụng cho http://abc.com/abcd/ (dư ký hiệu /)
- Không áp dụng cho http://abc.com/abcde (dư ký tự e)
5. Modifier ^~
Tương tự với trường hợp không dùng modifier, 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.
6. Modifier @
Đị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.
7. Thứ tự và độ ưu tiên khi tìm kiếm các khối location
server {
server_name abc.com;
location /files/ {
# Khả dụng cho những đường dẫn bắt đầu bằng "/files"
# Ví dụ /files/doc.txt, /files/, /files/temp/
}
location = /files/ {
# Chỉ áp dụng cho đường dẫn "/files/"
}
}
Khi khách hàng truy cập http://abc.com/files/doc.txt
, khối location đầu tiên được sử dụng. Tuy nhiên, khi họ truy cập http://abc.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ể:
- Các khối location với modifier
=
: nếu chuỗi được chỉ rõ trùng khớp với URI, Nginx giữ lại khối location này. - Các khối location không sử dụng modifier: nếu chuỗi được chỉ rõ trùng khớp với URI, Nginx giữ lại khối location này.
- Các khối location sử dụng modifier
^~
: 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. - Các khối location sử dụng modifier
~
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. - Các khối location không sử dụng modifier: 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.
Để rõ hơn, chúng ta cùng xem qua các ví dụ sau :
VD1:
server {
server_name abc.com;
# Block 1
location /doc {
[...] # đường dẫn bắt đầu với "/doc"
}
# Block 2
location ~* ^/document$ {
[...] #đường dẫn bắt chính xác "/document"
}
}
Khi khách hàng truy cập http://abc.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.
VD2:
server {
server_name abc.com;
# Block 1
location /document {
[...] # đường dẫn bắt đầu với "/document "
}
# Block 2
location ~* ^/document$ {
[...] #đường dẫn bắt chính xác "/document"
}
}
Khách hàng truy cập http://abc.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.
VD3:
server {
server_name abc.com;
# Block 1
location ^~ /doc {
[...] # đường dẫn bắt đầu với "/doc "
}
# Block 2
location ~* ^/document$ {
[...] #đường dẫn bắt chính xác "/document"
}
}
Khách hàng truy cập http://abc.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 cho truy cập trên.
Tài liệu tham khảo
https://www.nginx.com/resources/wiki/start/topics/examples/full/#
https://www.nginx.com/resources/admin-guide/installing-nginx-open-source/