Hướng dẫn viết lại URL với mod_rewrite cho Apache trên Ubuntu 16.04
Lời mở đầu
Điều kiện cần
Để làm theo các bước hướng dẫn này bạn sẽ cần:
- Một Cloud Server Ubuntu 16.04 tại ViCloud bao gồm người dùng sudo chưa root và tường lửa;
- Apache 2 đã được cài trong server của bạn;
Bước 1 — Enabling mod_rewrite
Đầu tiên chúng ta cần kích hoạt mod_rewrite
.Nó tuy có sẵn nhưng chưa được kích hoạt cho dù đã cài đặt Apache 2
sudo a2enmod rewrite
Câu lệnh này sẽ kích hoạt module hoặc thông báo cho bạn module đã được bật. Để lưu những thay đổi này, khởi động lại Apache
sudo systemctl restart apache2
mod_rewrite
đã được kích hoạt. Trong bước tiếp theo bạn sẽ tạo file .htaccess
sử dụng xác định quy tắc viết lại cho việc chuyển hướng.
Bước 2 — Setting Up .htaccess
File .htaccess cho phép chúng t thay đổi các quy tắc viết lại mà không cần truy cập vào file cấu hình server. Vì lí do này mà .htaccess cực kì quan trọng với bảo mật ứng dụng web. Chu kì đứng trước tên file sẽ chắc chắn rằng file này sẽ bị ẩn đi.
Note: Bất kì quy luật mà bạn đặt trong file .htaccess
có thể đặt trực tiếp trong file cấu hình server. Thực tế thì các tài liệu chính thức của Apache khuyên dùng sử dung file cấu hình server thay vì.htaccess
vì Apache sẽ xử lí no nhanh hơnTuy nhiên trong ví dụ đơn giản này, hiệu quả sẽ là không đáng kể. Thêm vào đó việc đặt các quy tắc trong .htaccess
rất bất tiện, đặc biệt với nhiều website trên cùng một server. Nó không yêu cầu khởi động lại server để lưu những thay đổi và cũng không cần quyền root để thay đổi quy luật đó, nó đơn giản hoá bảo trì và làm cho những thay đổi đó hoạt động được với những tài khoản không được cấp phép.Một số software nguồn mở như Wordpress và Joomla thường dựa trên file .htaccess
để thay đổi software và tạo ra thêm nhưng quy tắc nếu yêu cầu.
Bạn sẽ cần cài đặt và bảo mật một vài thứ trước khi chúng ta bắt đầu.
Apache mặc định cấm sử dụng file .htaccess để áp dụng các quy tắc mới, cho nên đầu tiên bạn cần cho phép thay đổi trên file đó. Mở cấu hình Apache mặc đijnh bằng cách sử dụng nano hoặc trình chỉnh sửa văn bản yêu thích của bạn
sudo nano /etc/apache2/sites-available/000-default.conf
Bên trong file bạn sẽ thấy khối
Options Indexes FollowSymLinks MultiViewsAllowOverride AllRequire all granted
. . .
Lưu và đóng file lại. Khởi động Apache để lưu những thay đổi.
sudo systemctl restart apache2
Tạo file
.htaccess
trong root web.
sudo nano /var/www/html/.htaccess
Thêm dòng này vào đầu file mới để bật engine viết lại.
RewriteEngine on
Lưu file và thoát.
Bạn đã có file .htaccess hoạt động dùng để thay đổi quy tắc định tuyến của ứng dụng web. Trong bước tiếp theo, chúng ta sẽ tạo một website mẫu dùng để xác định quy tắc viết lại.
Bước 3 — Configuring URL Rewrites
Chúng ta sẽ viết lại URL cơ bản về thay đổi các dòng URL ổn thành đường dẫn code thật. Cụ thể, bạn sẽ cho phép người dùng truy cập vào http://your_server_ip/about
.
Bắt đầu với tạo file rồi đặt tên là about.html trong root web.
sudo nano /var/www/html/about.html
Copy code HTML này vào trong file, sau đó lưu và đóng nó.
About Us
Bạn có thể truy cập trang tại địa chỉ http://your_server_ip/about.html, nhưng lưu ý rằng nếu bạn vẫn cố gắng truy cập http://your_server_ip/about , bạn sẽ thấy lỗi 404 Not Found . Nếu bạn truy cập trang bằng cách dùng about thay thế, quy luật viết lại sẽ hoạt động.
Tất cả RewriteRules
đều tuân theo format dưới đây:
RewriteRule pattern substitution [flags]
RewriteRule
chỉ rõ chỉ thị.pattern
là biểu thức khớp với chuỗi mong muốn từ URL và là kiểu người xem trong trình duyệtsubstitution
là đường dẫn tới URL thật, ví dụ như đường dẫn tới file server Apache.flags
là tham số tuỳ chọn có thể thay đổi cách quy tắc hoạt động.
Mở file
.htaccess
.
sudo nano /var/www/html/.htaccess
Sau dòng đầu tiên, thêm RewriteRule
được đánh dấu đỏ và lưu file lại
RewriteEngine onRewriteRule ^about$ about.html [NC]
Trong trường hợp này, ^about$ là pattern, about.html là substitution và [NC] là flag. Ví dụ của chúng ta sử dụng một vài dấu chữ với ý nghĩa đặc biệt:
- chi biết nơi bắt đầu của URL, sau your_server_ip/.
$
chỉ ra kết thúc của URL..about
nối với chuỗi "about".- about.html là file thực tại mà người dùng đang truy cập.
[NC]
là flag làm cho các quy tắc không chính xác.
Bây giờ bạn có thể truy cập vào http://your_server_ip/about trong trình duyệt của mình.Trên thực tế, với quy tắc nói bên trên, những URL sau sẽ nhắm tới about.html
:
http://your_server_ip/about
, bởi vì định nghĩa quy luậthttp://your_server_ip/About
, bởi vì quy luật không chính xác.http://your_server_ip/about.html
bởi vì tên hợp lệ ban đầu của file luôn luôn hoạt động.
Những dòng sau đây sẽ không :
http://your_server_ip/about/
, bởi vì quy tắc rõ ràng nêu rằng không có gì sau about bằng cách dùng dấu chữ $http://your_server_ip/contact
, vì nó không khớp với chuỗi about trong quy luật.
Bây giờ bạn đã có một file .htaccess có thể hoạt động cới quy tắc đơn giản mà bạn có thể thay đổi và mở rộng nhu cầu của mình. Trong phần tiếp theo, chúng tôi sẽ chỉ thêm hai ví dụ của các chỉ thị thường được sử dụng.
Ví dụ 1 — Simplifying Query Strings with RewriteRule
Ứng dụng web thường dùng chuỗi câu hỏi được nối vào một URL sử dụng dấu (?
) sau địa chỉ. Các tham số riêng được phân cách bằng dấu (&
) . Chuỗi câu hỏi có thể dùng để chuyển dữ liệu thêm vào giữa các trang ứng dụng độc lập.
Ví dụ, một trang tìm kiếm kết quả được viết bằng ngôn ngữ lập trình PHP có thể dùng URL kiểu như http://example.com/results.php?item=shirt&season=summer .Ở trong ví dụ này. 2 tham số thêm vào được chuyển tới kết quả result.php ảo, application script:item , với giá trị shirt ,và season với giá trị summer. Ứng dụng có thể dùng thông tin chuỗi câu hỏi để tạo lên page đúng cho người truy cập.
Apache rewrite rules thường được dùng để đơn giản hoá những đường linh dài dòng và khó chịu như bên trên thành những friendly URL dễ gõ hơn và dễ hiểu khi nhìn vào.Trong ví dụ này, chúng ta sẽ đi đơn giản hoá dòng link này http://example.com/shirt/summer. Gía trị tham số shirt và summer vẫn ở trong địa chỉ nhưng không ở trong chuỗi câu hỏi và tên script.
Đây là một quy tắc để thực hiện điều này:
RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
shirt/summer
is rõ ràng khớp trong địa chỉ yêu cầu và Apache được yêu cầu xử lí results.php?item=shirt&season=summer
thay vào đó.
Flag [QSA] được sử dụng rộng rãi trong viết lại quy luật. Chúng yêu cầu Apache kết nối thêm bất kì chuỗi câu hỏi nào tới URL đang được xử lí, cho nên nếu người truy cập gõ http://example.com/shirt/summer?page=2 thì server phản hồi vớiresults.php?item=shirt&season=summer&page=2. Không có phản hồi đó tức là chuỗi câu hỏi đã bị loại bỏ.
Trong khi phương pháp này đạt được những kết quả mong muốn, cả item name và season được mã hoá cứng thành quy tắc. Tức là có nghĩa là quy tắc này sẽ không hoại động với bất kì item nào như pants
hay bất cứ season nào nhưwinter
.
Để làm cho những quy tắc chung chung hơn, chúng ta có thể dùng biểu thức chính quy để nối những phần của địa chỉ ban đầu và dùng phần đó trong substitution pattern. Quy luật sau khi được thay đổi sẽ như sau:
RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
Nhóm biểu thức chính quy đầu tiên trong dấu ngoặc đơn khớp với chuỗi chứa các dấu chữ và số như shirt hoặc pants và lưu phần được nối là biến $1. Nhóm biểu thức chính quy thức hai trong dấu ngoặc đơn khớp chính xác summer
, winter
, fall
, hoặc spring
, và đơn giản lưu phần được nốilà $2
.
Phần đã được nối sau đó được dùng trong việc tìm ra kết quả URL trong biến item và season thay vì giá trị được mã hoá cứng shirt
và summer
mà ta sử dụng trước đó.
Ví dụ như những thứ bên trên sẽ chuyển đổi từ http://example.com/pants/summer
thành http://example.com/results.php?item=pants&season=summer
. Ví dụ đó cũng là một future proof, cho phép nhiều item và season được viết lại bằng một quy tắc.
Ví dụ 2 — Adding Conditions with Logic Using RewriteConds
Các quy tắc viết lại không nhất thiết phải luôn luôn được đánh giá từng cái một mà không có bất kì hạn chế nào. Chỉ thị RewriteCond cho phép chúng ta bổ sung các điều kiện để kiểm soát quy tắc viết lại của chúng ta khi chúng đang được tiến hành. Tất cả RewriteConds tuân theo format dưới đây:
RewriteCond TestString Condition [Flags]
RewriteCond
chỉ rõ chỉ thịRewriteCond
.TestString
is là chuỗi để test lên.Condition
là pattern hoặc điều kiện để nối.Flags
là tham số tuỳ chọn có thể thay đổi điều kiện và các quy tắc đánh giá.
Nếu RewriteCond đánh giá đúng thì tiếp đến RewriteRule sẽ được đánh giá. Nếu không, quy tắc này sẽ bị loại. Nhiều RewriteCond có thể được dùng sau cái khác với hành vi mặc định, tất cả phải được đánh giá đúng thì các quy tắc sau mới được đánh giá
Ví dụ hay coi như chúng ta muốn chuyển hướng tất cả request đến một file hoặc thư mục không tồn tại về trang chủ thay vì hiển thị 404 Not Found. Đó có thể làm đươc với dòng quy tắc sau:
RewriteCond %{REQUEST_FILENAME}!-f
RewriteCond %{REQUEST_FILENAME}!-d
RewriteRule . /
Với những điều trên:
%{REQUEST_FILENAME}
là chuỗi để check.Trong trường hợp này thì nó là tên file được yêu cầu mà hệ thống biến khả dụng cho mọi request.-f
à điều kiện được xây dựng để xác minh liệu rằng tên được yêu cầu có tồn tại trên đĩa hoặc file không.!
là toán tử phủ định. Khi được kết hợp,!-f
đánh giá đúng chỉ khi tên cụ thể không hề tồn tại hoặc không là một file.!-d
đơn giản đánh giá đúng chỉ khi tên cụ thể không tồn tại hoặc không phải là một tệp
RewriteRule
ở dòng cuối cùng sẽ có hiệu lực chỉ với những request tới file hoặc thư mục không tồn tại. The RewriteRule
bản thân nó rất đơn giản và chuyển hướng mọi request tới root website /.
Kết luận
mod_rewrite
là một module Apache rất hữu ích dùng để đảm bảo con người có thể đọc được các URL.Trong bài hướng dẫn này, bạn đã học cách sử dụng chỉ thị RewriteRule để chuyển hướng các URL, bao gồm các chuỗi câu hỏi. Bạn cũng đã học được cách chuyển hướng URL mọt cách có điều kiện bằng cách sử dụng chỉ thị RewriteCond.