Khi chúng ta làm việc với nginx, ngoài việc trả về static file, ta cũng có thể xây dựng hệ thống route linh hoạt, ứng dụng cho các môi trường Hosting hiệu quả.
Prefix Match là thuật ngữ miêu tả việc khớp URI không hoàn toàn. Để làm rõ về Prefix Match, chúng ta hãy tham khảo qua các vị dụ sau đây.
Đầu tiên, chúng ta sẽ tìm hiểu tới một context mới là location. Hãy theo dõi ví dụ dưới đây:
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location /demo {
return 200 "Hello";
}
}
}
Trong ví dụ trên:
root
directive thành location
context.location
context thường nằm bên trong liền kề vời server
contextVà nếu chúng ta thực hiện chạy câu lệnh kiểm thử như dưới đây
curl -i http://nglearns.test/demo
Kết quả:
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 15:59:07 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
# Hello
Tại đây chúng ta đã có thể dễ dàng lấy ra được nội dung "Hello".
Chúng ta sẽ thử gọi URL khác như sau
curl -i http://nglearns.test/demoA
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 15:59:07 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
# Hello
Trong trường hợp này, do nginx đang hiểu chỉ cần URI khớp "demo" là có thể truy cập vào ứng dụng.
Exact Match
là thuật ngữ dùng để mô tả việc khớp URI hoàn toàn. Hãy tham khảo ví dụ dưới đây.
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location = /demo {
return 200 "Hello";
}
}
}
Việc thêm dấu =
trước URI sẽ giúp cho nginx hiểu và chỉ cho phép truy cập khớp chính xác URI.
Chúng ta hãy kiểm tra trường hợp trùng URI
curl -I http://nglearns.test/demo
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
Tại trường hợp này ta đã request thành công và nhận được status là 200
Hãy thử với trường hợp không trùng URI
curl -I http://nglearns.test/demoA
Kết quả
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
Trong trường hợp này, ta đã không thể truy cập được vì request không hớp với URI đề ra.
Regex Match là thuật ngữ mô tả việc khớp URI theo một template đã đề ra. Hãy theo dõi ví dụ sau
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ~ /demo[0-9] {
return 200 "Hello";
}
}
}
Trong trường hợp này, chúng ta sử dụng dấu ~
để nói với nginx rằng việc trùng khớp URI sẽ được xác định bằng template /demo[0-9]
.
Hãy thực nghiệm thử trong ví dụ sau
curl -I http://nglearns.test/demo
Kết quả
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
Trong trường hợp này, request trả về lỗi 400 vì URI chưa khớp với template, vì ta cần 1 con số từ 0 tới 9 phía sau URI demo
Hãy thử nghiệm với trường hợp khác
curl -I http://nglearns.test/demo8
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
Trong trường hợp này, URI đã khớp với template và request thành công.
Hãy thử nghiệm với URL có chữ viết hoa
curl -I http://nglearns.test/demo8
Kết quả
# HTTP/1.1 404 Not Found
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:14:29 GMT
# Content-Type: text/html
# Content-Length: 162
# Connection: keep-alive
Trong trường hợp trên, ta request thất bại vì Regex Match
luôn hoạt động theo nguyên tắc Case Sensitive
, vậy nên request sẽ lỗi khi không tuân thủ chữ viết hoa và chữ thường.
Để khắc phục, ta sẽ config lại như sau
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ~* /demo[0-9] {
return 200 "Hello";
}
}
}
Bằng việc thêm dấu *
sau dấu ~
, ta sẽ giúp nginx hiểu trong trường hợp này ta sẽ không áp dụng Case Sensitive
.
Hãy kiểm thử lại qua ví dụ sau
curl -I http://nglearns.test/demo8
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Wed, 21 Apr 2021 16:15:04 GMT
# Content-Type: text/plain
# Content-Length: 29
# Connection: keep-alive
Nginx sẽ ưu tiên Regext Match hơn là Prefix Match.
Hãy tham khảo ví dụ với config như sau:
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location /Demo8 {
return 200 "prefix matched.\n";
}
location ~* /demo[0-9] {
return 200 "regex matched.\n";
}
}
}
Chúng ta sẽ kiểm thử với code như sau
curl -i http://nglearns.test/Demo8
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Thu, 22 Apr 2021 08:08:18 GMT
# Content-Type: text/plain
# Content-Length: 15
# Connection: keep-alive
# regex matched.
Trong ví dụ trên, tuy URL chúng ta muốn truy cập vào nhánh Prefix
nhưng kết quả trả về lại là nhành Regex
.
Để thay đổi lại quyền ưu tiên, hãy tham khảo ví dụ sau
events {
}
http {
server {
listen 80;
server_name nglearns.test;
location ^~ /Agatha8 {
return 200 "prefix matched.\n";
}
location ~* /agatha[0-9] {
return 200 "regex matched.\n";
}
}
}
Bằng cách thêm dấu ^ vào nhánh Prefix, ta sẽ đặt quyền của Prefix cao hơn.
Hãy kiểm thử qua câu lệnh sau
curl -i http://nglearns.test/Demo8
Kết quả
# HTTP/1.1 200 OK
# Server: nginx/1.18.0 (Ubuntu)
# Date: Thu, 22 Apr 2021 08:13:24 GMT
# Content-Type: text/plain
# Content-Length: 16
# Connection: keep-alive
# prefix matched.
Trong trường hợp trên, Prefix đã nhận request thành công sau khi đã nâng quyền ưu tiên.
Sau đây là danh sách quyền ưu tiên của các loại request.
MATCH | MODIFIER |
---|---|
Exact | = |
Preferential Prefix | ^~ |
Regex | ~ or ~* |
Prefix | none |