RewriteBase hoạt động như thế nào trong .htaccess


227

Tôi đã thấy điều này trong một vài .htaccessví dụ

RewriteBase /

Nó có vẻ hơi giống chức năng <base href="">của HTML.

Tôi tin rằng nó có thể tự động đưa giá trị của nó vào đầu RewriteRulecâu lệnh (có thể là câu lệnh mà không có dấu gạch chéo hàng đầu)?

Tôi không thể làm cho nó hoạt động đúng. Tôi nghĩ rằng việc sử dụng nó có thể rất hữu ích cho tính di động của trang web, vì tôi thường có một máy chủ phát triển khác với máy chủ sản xuất. Phương pháp hiện tại của tôi khiến tôi xóa các phần trong các RewriteRulebáo cáo của mình .

Bất cứ ai có thể giải thích cho tôi ngắn gọn làm thế nào để thực hiện nó?

Cảm ơn



RewriteBase chỉ hoạt động trong thư mục hoặc bối cảnh .htaccess ... tham khảo ngữ cảnh cho liên kết @SalmanPK được cung cấp.
Eddie B

1
Xem câu trả lời này cho một mô tả tốt. stackoverflow.com/a/2137593/292060
goodeye

1
Đây là một câu trả lời sâu hơn: stackoverflow.com/a/21348047/632951
Pacerier

Đây là câu trả lời 1 dòng: stackoverflow.com/a/46541685/632951
Pacerier

Câu trả lời:


102

Theo lời của tôi, sau khi đọc các tài liệu và thử nghiệm:

Bạn có thể sử dụng RewriteBaseđể cung cấp một cơ sở cho các bài viết của bạn. Xem xét điều này

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

# add trailing slash if missing
    rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]

Đây là một quy tắc thực tế mà tôi đã sử dụng để đảm bảo rằng các URL có dấu gạch chéo. Điều này sẽ chuyển đổi

http://www.example.com/~new/page

đến

http://www.example.com/~new/page/

Bằng cách có RewriteBaseở đó, bạn làm cho đường dẫn tương đối đi ra RewriteBasetham số.


10
Trước tiên, hãy tắt tham số RewriteBase - ý bạn là tham số RewriteRule? :)
Kissaki

1
Tôi muốn làm rõ một số chi tiết về htaccess .. ReWriteBase có đặt nó cho tất cả các quy tắc trong htaccess sau tuyên bố của nó không? Có cách nào để bỏ đặt nó, nó có thể được thiết lập lại không?
Damon

3
@Kissaki: Không, $1khớp với mẫu RewriteRule được ngoặc đơn, nhưng đường dẫn tương đối để thay thế xuất hiện tham số RewriteBase. Vì vậy, kết quả thay thế là /~new/$1/.
MrWhite

3
@Damon: Xem câu hỏi này liên quan đến nhiều RewriteBasechỉ thị. Nói tóm lại, bạn không thể có nhiều hơn một - Tôi nghĩ rằng lệnh cuối cùng RewriteBase sẽ thắng và ảnh hưởng đến toàn bộ tệp .htaccess.
MrWhite

24
-1; Câu trả lời này dường như đã giúp đỡ người khác, nhưng hoàn toàn mờ nhạt đối với tôi. Tôi có thể đoán rằng "Bạn có thể sử dụng RewriteBaseđể cung cấp cơ sở cho các bản viết lại của mình" - đó gần như chỉ là sự sắp xếp lại các từ - nhưng tôi không biết "căn cứ" là gì trong ngữ cảnh này, cũng như ý nghĩa của từ này như thế nào ví dụ bạn đã đưa ra sẽ khác nếu RewriteBasedòng bị xóa. Tôi sẽ chuyển sang hướng dẫn sử dụng ...
Mark Amery

89

RewriteBasechỉ đượ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:

  • Bạn đang sử dụng Aliaschỉ thị

  • Bạn đang sử dụng quy tắc viết lại .htaccess để thực hiện chuyển hướng HTTP (thay vì chỉ viết lại im lặng) cho các URL tương đối

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 RewriteRulecó 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 subdir2và yêu cầu /subdir2/e/f/gthì URI bị bắt là e/f/g.
  • Nếu quy tắc nằm trong subsubdirvà 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.phplà một đường dẫn tương đối, trái ngược với:

RewriteRule ^foo$ /bar.php [L]

trong đó /bar.phplà 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 Rcờ hoặc ngầm định vì bạn có http://hosttrong 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ì Rcờ, 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/foosẽ 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/foosẽ phục vụ, http://example.com/subdir1/bar.phpv.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ó.


Đối với tôi, tôi đã bỏ lỡ RewriteEngine On. Không cần trên 1and1 chẳng hạn nhưng nó được yêu cầu trên máy chủ chuyên dụng của tôi.
Portekoi

41

AFAIK, RewriteBase chỉ được sử dụng để khắc phục các trường hợp mod_rewrite đang chạy trong một .htaccesstệp không phải ở gốc của trang web và nó đoán đường dẫn web sai (trái ngược với đường dẫn hệ thống tệp) cho thư mục mà nó đang chạy. Vì vậy, nếu bạn có RewriteRule trong .htaccess trong thư mục ánh xạ tới http://example.com/myfolderbạn có thể sử dụng:

RewriteBase myfolder

Nếu mod_rewrite không hoạt động chính xác.

Cố gắng sử dụng nó để đạt được điều gì đó bất thường, thay vì khắc phục vấn đề này nghe có vẻ như là một công thức để trở nên rất bối rối.


2
Có cần phải kết thúc với một dấu gạch chéo?
Pacerier

@ mình, số Đã kiểm tra và giải thích phụ ở đây: stackoverflow.com/a/11443194/632951
Pacerier

23

RewriteBase chỉ hữu ích trong các tình huống mà bạn chỉ có thể đặt .htaccess vào thư mục gốc của trang web. Mặt khác, tốt hơn hết là bạn nên đặt các tệp .htaccess khác nhau của mình vào các thư mục khác nhau trên trang web của bạn và hoàn toàn bỏ qua lệnh RewriteBase.

Gần đây, đối với các trang web phức tạp, tôi đã gỡ chúng ra, bởi vì nó khiến việc triển khai các tệp từ thử nghiệm đến sống thêm một bước phức tạp.


22
Mặc dù đây có thể là lời khuyên tốt, nhưng đây không phải là một câu trả lời cho câu hỏi. Do đó, nó nên là một bình luận cho câu hỏi, không nhận được (như nhiều) upvote và chắc chắn không được chấp nhận như là câu trả lời.
Kissaki

3
"tốt hơn hết là đặt các tệp .htaccess khác nhau của bạn vào các thư mục khác nhau" - Tôi không chắc chắn rằng đây là lời khuyên tốt? Có các tệp .htaccess rải rác khắp trang web của bạn có thể khiến việc gỡ lỗi / bảo trì trở thành một cơn ác mộng. Tôi có thể nói rằng tốt hơn là có một tệp .htaccess trong thư mục gốc của trang web của bạn.
MrWhite

1
@ w3d Ngoài ra còn có vấn đề về thời gian: mỗi lần truy cập thư mục con, nhiều tệp .htaccess được phân tích cú pháp (từ thư mục gốc đến thư mục con hiện tại). Có nhiều tệp có thể làm giảm tốc độ của câu trả lời chung cho yêu cầu, trái ngược với một tệp trong thư mục gốc, ngay cả khi nó chứa rất nhiều quy tắc ..
Erenor Paz

19

Khi tôi phát triển, nó nằm trên một miền khác trong một thư mục. Khi tôi lấy một trang web trực tiếp, thư mục đó không còn tồn tại nữa. Sử dụng RewriteBase cho phép tôi sử dụng cùng một tệp .htaccess trong cả hai môi trường.

Khi sống:

RewriteBase /
# RewriteBase /dev_folder/

Khi phát triển:

# RewriteBase /
RewriteBase /dev_folder/

4
Tôi chắc chắn rằng điều này sẽ không luôn luôn hoạt động. Điều gì nếu bạn sử dụng %{REQUEST_URI}trong một RewriteCondchỉ thị chẳng hạn?
MrWhite

1
@ user1669830, Nếu bạn chỉ có một lần viết lại, bạn có thể vừa thêm cơ sở vào ngăn xếp viết lại stackoverflow.com/a/46541685/632951
Pacerier

18

Giải thích rõ ràng nhất mà tôi tìm thấy không phải là trong các tài liệu apache 2.4 hiện tại, mà là trong phiên bản 2.0 .

#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
#  Remember: /abc/def is the physical path of /xyz, i.e., the server
#            has a 'Alias /xyz /abc/def' directive e.g.

RewriteEngine On

#  let the server know that we were reached via /xyz and not
#  via the physical path prefix /abc/def
RewriteBase   /xyz

Làm thế nào nó hoạt động? Đối với các tin tặc apache, tài liệu 2.0 này tiếp tục cung cấp "thông tin chi tiết về các bước xử lý nội bộ".

Bài học rút ra: Trong khi chúng ta cần làm quen với "hiện tại", đá quý có thể được tìm thấy trong biên niên sử.


3

Lệnh này có thể thiết lập rõ ràng URL cơ sở cho các ghi lại của bạn. Nếu bạn muốn bắt đầu trong thư mục gốc của tên miền, bạn sẽ bao gồm dòng sau trước RewriteRule của bạn:

RewriteBase /

2

Tôi tin rằng đoạn trích này từ tài liệu của Apache, bổ sung tốt cho các câu trả lời trước:

Lệnh này là bắt buộc khi bạn sử dụng một đường dẫn tương đối để thay thế trong ngữ cảnh mỗi thư mục (htaccess) trừ khi một trong các điều kiện sau là đúng:

  • Yêu cầu ban đầu và thay thế, bên dưới DocumentRoot (trái ngược với khả năng tiếp cận bằng các phương tiện khác, chẳng hạn như Bí danh).

  • Đường dẫn hệ thống tập tin đến thư mục chứa RewriteRule, được thêm vào bởi sự thay thế tương đối cũng có giá trị như một đường dẫn URL trên máy chủ (điều này rất hiếm).

Như đã đề cập trước đây, trong các bối cảnh khác, nó chỉ hữu ích để làm cho quy tắc của bạn ngắn hơn. Hơn nữa, cũng như đã đề cập trước đây, bạn có thể đạt được điều tương tự bằng cách đặt tệp htaccess trong thư mục con.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.