thứ tự cú pháp mod_rewrite
mod_rewrite có một số quy tắc đặt hàng cụ thể ảnh hưởng đến việc xử lý. Trước khi mọi thứ được thực hiện, lệnh RewriteEngine On
này cần được đưa ra khi điều này bật xử lý mod_rewrite. Điều này nên được trước khi bất kỳ chỉ thị viết lại khác.
RewriteCond
trước đó RewriteRule
làm cho MỘT quy tắc phải tuân theo điều kiện. Bất kỳ RewriteRules nào sau đây sẽ được xử lý như thể chúng không phải chịu các điều kiện.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
Trong trường hợp đơn giản này, nếu người giới thiệu HTTP đến từ serverfault.com, hãy chuyển hướng yêu cầu blog đến các trang serverfault đặc biệt (chúng tôi chỉ đặc biệt như vậy). Tuy nhiên, nếu khối trên có thêm dòng RewriteRule:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
Tất cả các tệp .jpg sẽ chuyển đến các trang serverfault đặc biệt, không chỉ các tệp có tham chiếu cho biết nó đến từ đây. Đây rõ ràng không phải là mục đích của cách các quy tắc này được viết. Nó có thể được thực hiện với nhiều quy tắc RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Nhưng có lẽ nên được thực hiện với một số cú pháp thay thế phức tạp hơn.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteRule phức tạp hơn chứa các điều kiện để xử lý. Dấu ngoặc đơn cuối cùng, báo (html|jpg)
cho RewriteRule khớp với một trong hai html
hoặc jpg
để biểu diễn chuỗi khớp với giá trị $ 2 trong chuỗi được viết lại. Điều này giống hệt với khối trước đó, với hai cặp RewriteCond / RewriteRule, nó chỉ thực hiện trên hai dòng thay vì bốn.
Nhiều dòng RewriteCond được ngầm định ANDed và có thể được ORed rõ ràng. Để xử lý các tham chiếu từ cả ServerFault và Super User (OR rõ ràng):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
Để phục vụ các trang được giới thiệu ServerFault bằng trình duyệt Chrome (ẩn AND):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
cũng là thứ tự cụ thể vì nó chỉ định cách các lệnh sau RewriteRule
xử lý việc xử lý của chúng. Nó rất hữu ích trong các tập tin .htaccess. Nếu được sử dụng, nó sẽ là lệnh đầu tiên trong "RewriteEngine on" trong tệp .htaccess. Lấy ví dụ này:
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Điều này nói với mod_rewrite rằng URL cụ thể này hiện đang xử lý đã được gửi đến bằng cách http://example.com/blog/ thay vì đường dẫn thư mục vật lý (/ home / $ Username / public_html / blog) và để xử lý nó phù hợp. Bởi vì điều này, RewriteRule
coi đó là chuỗi bắt đầu sau "/ blog" trong URL. Đây là cùng một điều viết hai cách khác nhau. Một cái có RewriteBase, cái kia không có:
RewriteEngine On
##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg) $1.sf.$2
##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Như bạn có thể thấy, RewriteBase
cho phép viết lại các quy tắc để tận dụng đường dẫn của trang web vào nội dung thay vì máy chủ web , điều này có thể khiến chúng trở nên dễ hiểu hơn đối với những người chỉnh sửa các tệp đó. Ngoài ra, họ có thể làm cho các chỉ thị ngắn hơn, có một sự hấp dẫn thẩm mỹ.
Cú pháp kết hợp RewriteRule
RewriteRule tự nó có một cú pháp phức tạp để khớp chuỗi. Tôi sẽ che các cờ (những thứ như [PT]) trong phần khác. Bởi vì Sysadmin học bằng ví dụ thường xuyên hơn bằng cách đọc một trang người đàn ông, tôi sẽ đưa ra ví dụ và giải thích những gì họ làm.
RewriteRule ^/blog/(.*)$ /newblog/$1
Cấu .*
trúc khớp với bất kỳ ký tự đơn ( .
) nào hoặc nhiều lần ( *
). Việc đóng nó trong ngoặc đơn bảo nó cung cấp chuỗi được khớp với biến $ 1.
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
Trong trường hợp này, đầu tiên. * KHÔNG được đặt trong parens nên không được cung cấp cho chuỗi viết lại. Quy tắc này loại bỏ một cấp thư mục trên trang blog mới. (/blog/2009/sample.html trở thành /newblog/sample.html).
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
Trong trường hợp này, biểu thức dấu ngoặc đơn đầu tiên thiết lập một nhóm khớp. Điều này trở thành $ 1, không cần thiết và do đó không được sử dụng trong chuỗi viết lại.
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
Trong trường hợp này, chúng tôi sử dụng $ 1 trong chuỗi viết lại.
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
Quy tắc này sử dụng cú pháp khung đặc biệt chỉ định phạm vi ký tự . [0-9] khớp với các chữ số từ 0 đến 9. Quy tắc cụ thể này sẽ xử lý các năm từ 2000 đến 2099.
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
Điều này thực hiện tương tự như quy tắc trước đó, nhưng phần {2} bảo nó khớp với ký tự trước đó (một biểu thức ngoặc trong trường hợp này) hai lần.
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
Trường hợp này sẽ khớp với bất kỳ chữ cái viết thường nào trong biểu thức khớp thứ hai và làm như vậy cho càng nhiều ký tự càng tốt. Cấu \.
trúc bảo nó coi khoảng thời gian là một khoảng thời gian thực tế, không phải là ký tự đặc biệt trong các ví dụ trước. Tuy nhiên, nó sẽ bị hỏng nếu tên tệp có dấu gạch ngang trong đó.
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
Cái bẫy này đặt tên tệp với dấu gạch ngang trong đó. Tuy nhiên, như -
là một ký tự đặc biệt trong biểu thức ngoặc, nó phải là ký tự đầu tiên trong biểu thức.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Phiên bản này bẫy bất kỳ tên tệp nào bằng chữ cái, số hoặc -
ký tự trong tên tệp. Đây là cách bạn chỉ định nhiều bộ ký tự trong biểu thức ngoặc.
Cờ RewriteRule
Các cờ trên quy tắc viết lại có một loạt các ý nghĩa đặc biệt và usecase .
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
Cờ là phần [L]
cuối của biểu thức trên. Nhiều cờ có thể được sử dụng, phân tách bằng dấu phẩy. Các tài liệu được liên kết mô tả từng cái, nhưng dù sao thì đây là:
L = Lần cuối. Dừng xử lý RewriteRules khi cái này khớp. Số lượng đặt hàng!
C = Chuỗi. Tiếp tục xử lý RewriteRule tiếp theo. Nếu quy tắc này không khớp, quy tắc tiếp theo sẽ không được thực thi. Thêm về điều này sau.
E = Đặt biến môi trường. Apache có các biến môi trường khác nhau có thể ảnh hưởng đến hành vi của máy chủ web.
F = Cấm. Trả về lỗi 403-Cấm nếu quy tắc này phù hợp.
G = Đã qua rồi. Trả về lỗi 410-Gone nếu quy tắc này phù hợp.
H = Xử lý. Buộc yêu cầu được xử lý như thể đó là loại MIME được chỉ định.
N = Tiếp theo. Buộc quy tắc bắt đầu lại từ đầu và khớp lại. HÃY CẨN THẬN! Vòng lặp có thể dẫn đến.
NC = Không có trường hợp. Cho phépjpg
để phù hợp với cả jpg và JPG.
NE = Không lối thoát. Ngăn chặn việc viết lại các ký tự đặc biệt (.? # & Vv) thành các mã tương đương mã hex của chúng.
NS = Không có cuộc chinh phục. Nếu bạn đang sử dụng bao gồm phía máy chủ, điều này sẽ ngăn các kết quả khớp với các tệp được bao gồm.
P = Proxy. Buộc quy tắc được xử lý bởi mod_proxy. Cung cấp nội dung một cách minh bạch từ các máy chủ khác, bởi vì máy chủ web của bạn tìm nạp nó và phục vụ lại nó. Đây là một lá cờ nguy hiểm, vì một lá cờ được viết kém sẽ biến máy chủ web của bạn thành một proxy mở và Điều đó thật tệ.
PT = Đi qua. Hãy tính đến các câu lệnh Bí danh trong kết hợp RewriteRule.
QSA = QSAppend. Khi chuỗi gốc chứa truy vấn ( http://example.com/thing?asp=foo) nối chuỗi truy vấn ban đầu vào chuỗi viết lại. Thông thường nó sẽ bị loại bỏ. Quan trọng đối với nội dung động.
R = Chuyển hướng. Cung cấp chuyển hướng HTTP đến URL được chỉ định. Cũng có thể cung cấp mã chuyển hướng chính xác [R = 303]. Rất giống với RedirectMatch
, nhanh hơn và nên được sử dụng khi có thể.
S = Bỏ qua. Bỏ qua quy tắc này.
T = Loại. Chỉ định loại mime của nội dung được trả về. Rất giống với AddType
chỉ thị.
Bạn biết làm thế nào tôi nói rằng RewriteCond
áp dụng cho một và chỉ một quy tắc? Chà, bạn có thể vượt qua điều đó bằng cách xâu chuỗi.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Vì RewriteRule đầu tiên có cờ Chain, quy tắc ghi lại thứ hai sẽ thực thi khi lần đầu tiên thực hiện, đó là khi quy tắc RewriteCond trước đó được khớp. Tiện dụng nếu các biểu thức chính quy của Apache làm cho não của bạn bị tổn thương. Tuy nhiên, phương pháp tất cả trong một dòng tôi chỉ đến trong phần đầu tiên nhanh hơn từ quan điểm tối ưu hóa.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Điều này có thể được thực hiện đơn giản hơn thông qua các cờ:
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
Ngoài ra, một số cờ cũng áp dụng cho RewriteCond. Đáng chú ý là NoCase.
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
Sẽ khớp với "ServerFault.com"