RewriteBase
chỉ được áp dụng cho mục tiêu của quy tắc viết lại tương đối .
Sử dụng RewriteBase như thế này ...
RewriteBase /folder/
RewriteRule a\.html b.html
về cơ bản giống như ...
RewriteRule a\.html /folder/b.html
Nhưng khi tệp .htaccess ở bên trong /folder/
thì điều này cũng trỏ đến cùng một mục tiêu:
RewriteRule a\.html b.html
Mặc dù các tài liệu ngụ ý luôn sử dụng a RewriteBase
, Apache thường phát hiện chính xác nó cho các đường dẫn trong DocumentRoot trừ khi:
Trong những trường hợp này, bạn có thể thấy rằng bạn cần chỉ định RewriteBase.
Tuy nhiên, vì đó là một chỉ thị khó hiểu, nói chung tốt hơn là chỉ định các URI tuyệt đối (còn gọi là 'gốc tương đối') trong các mục tiêu viết lại của bạn. Các nhà phát triển khác đọc quy tắc của bạn sẽ nắm bắt những điều này dễ dàng hơn.
Trích dẫn từ câu trả lời sâu sắc tuyệt vời của Jon Lin tại đây :
Trong tệp htaccess, mod_rewrite hoạt động tương tự như một <Directory>
hoặc vùng <Location>
chứa. và RewriteBase
được sử dụng để cung cấp một cơ sở đường dẫn tương đối.
Ví dụ: giả sử bạn có cấu trúc thư mục này:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
Vì vậy, bạn có thể truy cập:
http://example.com/
(nguồn gốc)
http://example.com/subdir1
(tiểu thư1)
http://example.com/subdir2
(subir2)
http://example.com/subdir2/subsubdir
(tiểu mục)
URI được gửi qua a RewriteRule
có liên quan đến thư mục chứa tệp htaccess. Vì vậy, nếu bạn có:
RewriteRule ^(.*)$ -
- Trong htaccess gốc và yêu cầu là
/a/b/c/d
, thì URI ( $1
) đã bắt là a/b/c/d
.
- Nếu quy tắc nằm trong
subdir2
và yêu cầu /subdir2/e/f/g
thì URI bị bắt là e/f/g
.
- Nếu quy tắc nằm trong
subsubdir
và yêu cầu là /subdir2/subsubdir/x/y/z
, thì URI bị bắt là x/y/z
.
Thư mục mà quy tắc nằm trong đó có phần bị tước khỏi URI. Cơ sở viết lại không ảnh hưởng đến điều này, đây đơn giản là cách hoạt động của mỗi thư mục.
Có gì căn cứ viết lại không làm, là cung cấp một cơ sở URL đường dẫn ( không một cơ sở tập tin đường dẫn) cho bất kỳ đường dẫn tương đối trong mục tiêu của quy tắc . Vì vậy, nói rằng bạn có quy tắc này:
RewriteRule ^foo$ bar.php [L]
Đây bar.php
là một đường dẫn tương đối, trái ngược với:
RewriteRule ^foo$ /bar.php [L]
trong đó /bar.php
là một con đường tuyệt đối. Đường dẫn tuyệt đối sẽ luôn là "root" (trong cấu trúc thư mục ở trên). Điều đó có nghĩa là bất kể quy tắc có nằm trong "root", "subir1", "subsubdir", v.v., /bar.php
đường dẫn luôn ánh xạ tới http://example.com/bar.php
.
Nhưng quy tắc khác, với đường dẫn tương đối, nó dựa trên thư mục chứa quy tắc. Vì vậy, nếu
RewriteRule ^foo$ bar.php [L]
là trong "root" và bạn đi đến http://example.com/foo
, bạn được phục vụ http://example.com/bar.php
. Nhưng nếu quy tắc đó nằm trong thư mục "subir1" và bạn truy cập http://example.com/subdir1/foo
, bạn sẽ được phục vụ http://example.com/subdir1/bar.php
. vv Điều này đôi khi hoạt động và đôi khi không, như tài liệu nói, nó được cho là yêu cầu cho các đường dẫn tương đối, nhưng hầu hết thời gian nó dường như hoạt động. Ngoại trừ khi bạn đang chuyển hướng (sử dụng R
cờ hoặc ngầm định vì bạn có http://host
trong mục tiêu của quy tắc của mình). Điều đó có nghĩa là quy tắc này:
RewriteRule ^foo$ bar.php [L,R]
nếu nó nằm trong thư mục "subir2" và bạn truy cập http://example.com/subdir2/foo
, mod_rewrite sẽ nhầm đường dẫn tương đối là đường dẫn tệp thay vì đường dẫn URL và vì R
cờ, cuối cùng bạn sẽ được chuyển hướng đến một cái gì đó như : http://example.com/var/www/localhost/htdocs/subdir1
. Đó rõ ràng không phải là những gì bạn muốn.
Đây là đâu RewriteBase
xuất hiện. Lệnh này cho mod_rewrite biết phải thêm gì vào đầu mỗi đường dẫn tương đối. Vì vậy, nếu tôi có:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
trong "subsubdir", http://example.com/subdir2/subsubdir/foo
sẽ thực sự phục vụ tôi http://example.com/blah/bar.php
. "Bar.php" được thêm vào cuối cơ sở. Trong thực tế, ví dụ này thường không phải là những gì bạn muốn, bởi vì bạn không thể có nhiều cơ sở trong cùng một thư mục chứa hoặc tập tin htaccess.
Trong hầu hết các trường hợp, nó được sử dụng như thế này:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
trong đó các quy tắc sẽ nằm trong thư mục "subir1" và
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
sẽ nằm trong thư mục "subsubdir".
Điều này một phần cho phép bạn làm cho các quy tắc của bạn có thể di động, vì vậy bạn có thể thả chúng vào bất kỳ thư mục nào và chỉ cần thay đổi cơ sở thay vì một loạt các quy tắc. Ví dụ: nếu bạn có:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
như vậy http://example.com/subdir1/foo
sẽ phục vụ, http://example.com/subdir1/bar.php
v.v. Và giả sử bạn đã quyết định chuyển tất cả các tệp và quy tắc đó sang thư mục "subsubdir". Thay vì thay đổi mọi trường hợp /subdir1/
thành /subdir2/subsubdir/
, bạn có thể đã có một cơ sở:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
Và sau đó khi bạn cần di chuyển các tệp đó và các quy tắc sang thư mục khác, chỉ cần thay đổi cơ sở:
RewriteBase /subdir2/subsubdir/
và đó là nó.