RewriteRule vs Redirect trong .htaccess | Khi nào dùng cái nào【2026】
Path cũ → URL mới cố định: dùng Redirect 301 (mod_alias) — ngắn, dễ đọc. Ép HTTPS, www/apex, điều kiện Host, regex nhiều path: dùng RewriteRule + RewriteCond (mod_rewrite). Đừng trộn hai kiểu map ngược chiều nhau — đó là nguồn redirect loop phổ biến trên shared hosting. Generator trên htaccess generator xuất RewriteRule với mã 301/302 — hợp khi bạn cần pattern linh hoạt hơn một dòng Redirect.
Freelancer và team outsourcing Việt Nam hay nhận ticket: “Chuyển domain xong, Google vẫn vào URL cũ” hoặc “Ép HTTPS làm site trắng 500”. Nửa số lần không phải vì chọn sai 301/302 (đã có bài riêng), mà vì chọn sai lớp cú pháp: copy Redirect từ Stack Overflow rồi thêm RewriteRule ép www — hai module Apache xử lý theo thứ tự khó đoán, dễ loop.
Bài này tập trung RewriteRule vs Redirect — khi nào dùng cái nào, ví dụ cụ thể, lỗi thường gặp trên Hostinger / Vietnix / cPanel Apache, và cách dùng generator mà không tin mù output.
Bài viết này giúp bạn
- Phân biệt mod_alias (
Redirect) và mod_rewrite (RewriteRule) - Quyết định theo 3 tình huống: path cố định, chuẩn hóa Host/HTTPS, rewrite nội bộ
- Đọc đúng output dạng
RewriteEngine+RewriteCond+RewriteRule - Tránh loop, 500, và xung đột khi trộn hai kiểu
- Checklist trước khi bàn giao khách
Muốn sâu về 301 vs 302 / SEO migrate: đọc Redirect 301 vs 302 trong .htaccess. Bài này giả định bạn đã biết 301 = vĩnh viễn, 302 = tạm.
Hai module, hai tư duy
Apache không có một lệnh “redirect duy nhất”. Có ít nhất hai cách phổ biến trên .htaccess:
| Cơ chế | Module | Cú pháp điển hình | Điểm mạnh |
|---|---|---|---|
| Redirect | mod_alias | Redirect 301 /old /new | Ngắn, rõ ràng, đủ cho map 1-1 |
| RewriteRule | mod_rewrite | RewriteRule ^old$ /new [R=301,L] | Regex, điều kiện, rewrite nội bộ |
Redirect (mod_alias)
Redirect 301 /blog-cu https://example.com/blog
Redirect 302 /promo-tet https://example.com/landing-tet
- Path nguồn thường là prefix (tùy phiên bản/cấu hình — luôn test).
- Không cần
RewriteEngine On. - Khó gắn điều kiện kiểu “chỉ khi Host = www” trong cùng một dòng sạch.
RewriteRule (mod_rewrite)
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
- Cần
RewriteEngine On. RewriteCondlọc theo HTTPS, Host, query, header…- Cờ
[R=301,L]: R = redirect HTTP; L = dừng rule tiếp theo trong chuỗi rewrite.
Tóm tắt nhanh: muốn “đổi đường dẫn A thành B” → Redirect. Muốn “nếu điều kiện X thì chuyển / viết lại” → RewriteRule.
Bảng quyết định: dùng cái nào?
| Mục tiêu | Nên dùng | Vì sao |
|---|---|---|
| Vài URL cố định sau redesign | Redirect 301 | Ít module, dễ review trong PR, ít regex sai |
| Ép HTTP → HTTPS | RewriteRule + Cond HTTPS | Cần điều kiện; Redirect thuần khó làm sạch |
| www ↔ apex (không www) | RewriteRule + Cond HTTP_HOST | Phụ thuộc Host header |
| Nhiều slug blog theo pattern | RewriteRule regex | Một rule thay hàng chục Redirect |
| Rewrite nội bộ (URL đẹp, không đổi trình duyệt) | RewriteRule không có R= | Redirect luôn báo Location ra ngoài |
| Staging tạm trỏ landing | Redirect 302 hoặc Rewrite [R=302] | Tạm thời — nhớ đổi 301 khi xong |
Case A — Path cố định (nên Redirect)
Khách đổi /gioi-thieu.html → /about/. Không đụng HTTPS (đã ổn):
Redirect 301 /gioi-thieu.html https://shop.vn/about/
Junior hay over-engineer thành RewriteRule 4 dòng — không sai, nhưng khó đọc hơn khi audit sau 6 tháng.
Case B — Chuẩn hóa Host + HTTPS (nên RewriteRule)
Shared hosting VN thường để lẫn http://, https://, www. và apex. Một chuỗi rule điển hình:
RewriteEngine On
# HTTP → HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# apex → www (ví dụ chọn www làm canonical)
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
Làm bằng nhiều Redirect rời dễ tạo hai bước redirect (http→https rồi lại www→apex) — chậm và xấu cho SEO. Gộp logic bằng RewriteCond rõ hơn.
Case C — Chỉ rewrite nội bộ (RewriteRule không redirect)
RewriteEngine On
RewriteRule ^san-pham/([0-9]+)/?$ /product.php?id=$1 [L,QSA]
Trình duyệt vẫn thấy /san-pham/42/ — không phải Redirect. Nếu lỡ thêm [R=301] sẽ lộ product.php ra ngoài — hay gặp khi copy nhầm từ tutorial.
Output generator trông như thế nào?
Công cụ htaccess generator trên Kawa Dev Tools chạy trong trình duyệt (không upload rule lên server lạ). Bạn chọn 301 hoặc 302, nhập path nguồn và URL đích — output dạng:
RewriteEngine On
RewriteCond %{REQUEST_URI} /trang-cu
RewriteRule .* https://example.com/trang-moi [R=301,L]
Cách đọc nhanh
RewriteEngine On— bật mod_rewrite cho context này.RewriteCond %{REQUEST_URI} ...— lọc URI khớp nguồn bạn nhập.RewriteRule .* đích [R=301,L]— redirect với mã đã chọn, dừng chuỗi rule.
Khi nào tin generator: path/pattern rõ, bạn hiểu 301 vs 302, sẽ test curl -I.
Khi nào viết tay Redirect ngắn hơn: một hoặc hai path cố định, không cần Cond — đừng bắt buộc mọi thứ qua RewriteRule.
Lưu ý: placeholder nguồn có thể là regex. Pattern quá rộng (.*) dễ nuốt mọi request — luôn thu hẹp và test trên staging.
Lỗi thực tế hay gặp ở VN
1. Trộn Redirect và RewriteRule ngược chiều
Redirect 301 /a /b
# ... chỗ khác ...
RewriteRule ^b$ /a [R=301,L]
→ Loop. Triệu chứng: trình duyệt “quá nhiều lần chuyển hướng”. Fix: một chiều duy nhất về canonical.
2. Nginx / OpenLiteSpeed “tưởng” chạy .htaccess
Một số VPS cài Nginx phía trước; .htaccess không được đọc. Rule “chạy trên máy local Apache” nhưng production im lặng. Hỏi host panel: Apache hay Nginx? Có Cloudflare Redirect không?
3. Sửa .htaccess → 500 toàn site
Thiếu đóng ngoặc, ký tự lạ từ Word copy, hoặc RewriteEngine trùng. Luôn backup file cũ; giữ SSH/file manager mở để rollback trong 30 giây.
4. Chỉ test bằng Chrome thường
Redirect bị cache rất dai. Dùng:
curl -I https://example.com/trang-cu
Xem HTTP/1.1 301 và header Location:. Hoặc cửa sổ ẩn danh + disable cache trong DevTools.
5. 302 “cho chắc” khi migrate xong
Vẫn gặp: sợ 301 không đảo ngược được nên để 302 mãi. Google giữ tín hiệu ở URL cũ lâu hơn. Migrate xong → 301. Chi tiết: bài 301 vs 302.
Case study ngắn
Freelancer chuyển blog WordPress → static
- Cần:
/2023/05/hello→/blog/hello(hàng chục slug). - Chọn: vài
RewriteRuleregex hoặc map export, không hàng trămRedirectcopy tay. - Generator: dùng cho từng nhóm pattern quan trọng; review Cond trước khi dán production.
Shop nhỏ ép HTTPS sau khi gắn Let’s Encrypt
- Cần: mọi
http://→https://, giữ path. - Chọn:
RewriteCond %{HTTPS}+RewriteRule— không dùngRedirecttừng trang. - Kiểm tra thêm: mixed content (ảnh
http://) là chuyện HTML/CDN, không phải .htaccess giải hết.
Checklist trước khi bàn giao
- Mục tiêu là map path, chuẩn hóa Host/HTTPS, hay rewrite nội bộ?
- Đã chọn một canonical (HTTPS + www hoặc apex)?
- Path cố định ít → ưu tiên
Redirect; có Cond/regex →RewriteRule. - Backup
.htaccesscũ; có cách rollback. curl -Iít nhất: trang chủ, 2–3 URL cũ, bản http và www.- Không còn chuỗi redirect > 1 bước nếu có thể gộp.
- Document cho khách: “đây là 301 vĩnh viễn” hoặc “302 tạm đến ngày X”.
Cách dùng nhanh trên Kawa
- Mở htaccess generator
- Chọn 301 (migrate) hoặc 302 (tạm)
- Nhập path/pattern nguồn và URL đích đầy đủ (
https://...) - Copy block
RewriteEngine/RewriteCond/RewriteRule - Dán vào
.htaccess(sau backup), test bằngcurl -I
Công cụ không thay kiến thức chọn Redirect thuần vs Rewrite — nó giúp draft rule Rewrite nhanh và chạy local trên trình duyệt.
Câu hỏi thường gặp
Redirect và RewriteRule khác nhau thế nào?
Redirect (mod_alias) ngắn cho map path cố định. RewriteRule (mod_rewrite) cho regex và điều kiện Host/HTTPS. Xem bảng quyết định ở trên.
Khi nào chỉ cần Redirect 301?
Vài URL cố định, không cần Cond theo Host/HTTPS. Một dòng Redirect 301 dễ audit hơn chuỗi Rewrite.
Hosting Nginx thì sao?
.htaccess không chạy. Dùng nginx.conf, panel host, hoặc Cloudflare Redirect Rules.
Generator xuất RewriteRule — có sai không?
Không sai: linh hoạt cho pattern và gắn [R=301|302,L]. Path cực đơn giản bạn vẫn có thể viết Redirect tay cho gọn.
Tránh loop thế nào?
Một chiều về canonical; không map ngược; kiểm curl -I; backup trước khi sửa.