Bagaimana cara kerja RewriteBase di .htaccess

Mar 31 2009

Saya telah melihat ini dalam beberapa .htaccesscontoh

RewriteBase /

Tampaknya fungsinya agak mirip dengan <base href="">HTML.

Saya percaya itu dapat secara otomatis menambahkan nilainya ke awal RewriteRulepernyataan (mungkin yang tanpa garis miring)?

Saya tidak bisa membuatnya berfungsi dengan baik. Saya pikir penggunaannya bisa sangat berguna untuk portabilitas situs, karena saya sering memiliki server pengembangan yang berbeda dengan server produksi. Metode saya saat ini membuat saya menghapus sebagian dari RewriteRulepernyataan saya .

Adakah yang bisa menjelaskan kepada saya secara singkat bagaimana menerapkannya?

Terima kasih

Jawaban

105 alex Apr 01 2009 at 05:28

Dengan kata-kata saya sendiri, setelah membaca dokumen dan bereksperimen:

Anda dapat menggunakan RewriteBasesebagai dasar untuk penulisan ulang Anda. Pertimbangkan ini

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

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

Ini adalah aturan nyata yang saya gunakan untuk memastikan bahwa URL memiliki garis miring. Ini akan mengubah

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

untuk

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

Dengan memiliki di RewriteBasesana, Anda membuat jalur relatif keluar dari RewriteBaseparameter.

92 SimonEast Jan 13 2015 at 00:36

RewriteBasehanya diterapkan pada sasaran dari kerabat aturan penulisan ulang.

  • Menggunakan RewriteBase seperti ini ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • pada dasarnya sama dengan ...

    RewriteRule a\.html /folder/b.html
    
  • Tetapi ketika file .htaccess ada di dalam /folder/maka ini juga mengarah ke target yang sama:

    RewriteRule a\.html b.html
    

Meskipun dokumen menyiratkan selalu menggunakan a RewriteBase, Apache biasanya mendeteksinya dengan benar untuk jalur di bawah DocumentRoot kecuali:

  • Anda menggunakan Aliasarahan

  • Anda menggunakan aturan rewrite .htaccess untuk melakukan pengalihan HTTP (bukan hanya menulis ulang secara diam-diam) ke URL relatif

Dalam kasus ini, Anda mungkin perlu menentukan RewriteBase.

Namun, karena ini adalah direktif yang membingungkan, biasanya lebih baik menetapkan URI absolut (alias 'root relative') dalam target penulisan ulang Anda. Pengembang lain yang membaca aturan Anda akan memahami ini dengan lebih mudah.



Mengutip dari jawaban mendalam yang sangat baik dari Jon Lin di sini :

Dalam file htaccess, mod_rewrite berfungsi mirip dengan <Directory>atau <Location>container. dan RewriteBasedigunakan untuk menyediakan basis jalur relatif.

Misalnya, Anda memiliki struktur folder ini:

DocumentRoot
|-- subdir1
`-- subdir2
    `-- subsubdir

Jadi Anda dapat mengakses:

  • http://example.com/ (akar)
  • http://example.com/subdir1 (subdir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (subdirektori)

URI yang dikirim melalui a RewriteRulerelatif terhadap direktori yang berisi file htaccess. Jadi jika Anda memiliki:

RewriteRule ^(.*)$ - 
  • Di root htaccess, dan permintaannya adalah /a/b/c/d, maka URI yang diambil ( $1) adalah a/b/c/d.
  • Jika aturan ada subdir2dan permintaannya adalah /subdir2/e/f/gURI yang diambil adalah e/f/g.
  • Jika aturan ada di subsubdir, dan permintaannya ada /subdir2/subsubdir/x/y/z, URI yang diambil adalah x/y/z.

Direktori tempat aturan berada memiliki bagian yang dilucuti dari URI. Basis penulisan ulang tidak mempengaruhi hal ini, ini hanyalah cara kerja per direktori.

Apa dasar menulis ulang tidak lakukan, adalah memberikan dasar URL-jalan ( bukan basis berkas-jalan) untuk setiap path relatif dalam sasaran aturan ini . Jadi katakanlah Anda memiliki aturan ini:

RewriteRule ^foo$ bar.php [L]

Ini bar.phpadalah jalur relatif, sebagai lawan dari:

RewriteRule ^foo$ /bar.php [L]

dimana /bar.phpadalah jalur absolut. Path absolut akan selalu menjadi "root" (dalam struktur direktori di atas). Artinya, terlepas dari apakah aturan ada di "root", "subdir1", "subsubdir", dll. /bar.phpJalur selalu dipetakan http://example.com/bar.php.

Tetapi aturan lainnya, dengan jalur relatif, ini didasarkan pada direktori tempat aturan tersebut berada. Jadi, jika

RewriteRule ^foo$ bar.php [L]

ada di "root" dan Anda pergi ke http://example.com/foo, Anda akan dilayani http://example.com/bar.php. Tetapi jika aturan itu ada di direktori "subdir1", dan Anda pergi ke http://example.com/subdir1/foo, Anda akan dilayani http://example.com/subdir1/bar.php. dll. Ini terkadang berfungsi dan terkadang tidak, seperti yang dikatakan dalam dokumentasi, seharusnya diperlukan untuk jalur relatif, tetapi sebagian besar waktu tampaknya berfungsi. Kecuali saat Anda mengalihkan (menggunakan Rbendera, atau secara implisit karena Anda ada http://hostdi target aturan Anda). Artinya aturan ini:

RewriteRule ^foo$ bar.php [L,R]

jika itu dalam "subdir2" direktori, dan Anda pergi ke http://example.com/subdir2/foo, mod_rewrite akan kesalahan path relatif sebagai file-jalan bukannya URL-jalan dan karena Rbendera, Anda akan berakhir mendapatkan diarahkan ke sesuatu seperti: http://example.com/var/www/localhost/htdocs/subdir1. Yang jelas bukan yang Anda inginkan.

Di sinilah RewriteBasemasuk. Direktif memberitahu mod_rewrite apa yang harus ditambahkan ke awal setiap jalur relatif. Jadi jika saya memiliki:

RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]

di "subsubdir", http://example.com/subdir2/subsubdir/fooakan benar-benar melayani saya http://example.com/blah/bar.php. The "bar.php" ditambahkan ke akhir basis. Dalam praktiknya, contoh ini biasanya bukan yang Anda inginkan, karena Anda tidak dapat memiliki beberapa basis dalam penampung direktori atau file htaccess yang sama.

Dalam kebanyakan kasus, ini digunakan seperti ini:

RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]

di mana aturan tersebut akan berada di direktori "subdir1" dan

RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]

akan berada di direktori "subsubdir".

Ini sebagian memungkinkan Anda membuat aturan portabel, sehingga Anda dapat meletakkannya di direktori mana pun dan hanya perlu mengubah basisnya, bukan sekumpulan aturan. Misalnya jika Anda memiliki:

RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L] RewriteRule ^blah2$ /subdir1/blah2.php [L]
...

sedemikian rupa sehingga http://example.com/subdir1/fooakan berfungsi, http://example.com/subdir1/bar.phpdll. Dan katakanlah Anda memutuskan untuk memindahkan semua file dan aturan tersebut ke direktori "subsubdir". Alih-alih mengubah setiap contoh /subdir1/menjadi /subdir2/subsubdir/, Anda bisa saja memiliki basis:

RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L] RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...

Dan kemudian ketika Anda perlu memindahkan file dan aturan tersebut ke direktori lain, cukup ubah basisnya:

RewriteBase /subdir2/subsubdir/

dan hanya itu.

41 rjmunro Jan 20 2012 at 13:41

AFAIK, RewriteBase hanya digunakan untuk memperbaiki kasus di mana mod_rewrite berjalan di .htaccessfile yang bukan di root situs dan menebak jalur web yang salah (berlawanan dengan jalur sistem file) untuk folder tempat menjalankannya. Jadi, jika Anda memiliki RewriteRule dalam .htaccess di folder yang memetakan ke http://example.com/myfolderAnda dapat menggunakan:

RewriteBase myfolder

Jika mod_rewrite tidak berfungsi dengan benar.

Mencoba menggunakannya untuk mencapai sesuatu yang tidak biasa, daripada memperbaiki masalah ini kedengarannya seperti resep untuk menjadi sangat membingungkan.

23 ThomasHunterII Dec 13 2010 at 20:28

RewriteBase hanya berguna dalam situasi di mana Anda hanya dapat meletakkan .htaccess di root situs Anda. Jika tidak, Anda mungkin lebih baik menempatkan file .htaccess yang berbeda di direktori yang berbeda di situs Anda dan sepenuhnya menghilangkan direktif RewriteBase.

Akhir-akhir ini, untuk situs yang kompleks, saya telah menghapusnya, karena itu membuat penerapan file dari pengujian menjadi tinggal satu langkah lagi menjadi rumit.

20 user1669830 Nov 30 2012 at 20:32

Saat saya kembangkan, itu ada di domain yang berbeda di dalam folder. Saat saya menjalankan situs, folder itu tidak ada lagi. Menggunakan RewriteBase memungkinkan saya menggunakan file .htaccess yang sama di kedua lingkungan.

Saat live:

RewriteBase /
# RewriteBase /dev_folder/

Saat mengembangkan:

# RewriteBase /
RewriteBase /dev_folder/
18 DWB Mar 24 2013 at 14:39

Penjelasan paling jelas yang saya temukan tidak ada di dokumen apache 2.4 saat ini, tetapi di versi 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

Bagaimana cara kerjanya? Bagi Anda para peretas apache, dokumen 2.0 ini selanjutnya memberikan "informasi terperinci tentang langkah-langkah pemrosesan internal."

Hal yang dipelajari: Meskipun kita perlu terbiasa dengan "saat ini", permata dapat ditemukan dalam catatan sejarah.

3 SandeepGoyal Oct 16 2011 at 14:10

Perintah ini secara eksplisit dapat mengatur URL dasar untuk penulisan ulang Anda. Jika Anda ingin memulai di root domain Anda, Anda harus menyertakan baris berikut sebelum RewriteRule Anda:

RewriteBase /
2 Noname Feb 13 2013 at 01:39

Saya percaya kutipan dari dokumentasi Apache ini, melengkapi dengan baik jawaban sebelumnya:

Direktif ini diperlukan saat Anda menggunakan jalur relatif dalam substitusi dalam konteks per direktori (htaccess) kecuali salah satu dari kondisi berikut ini benar:

  • Permintaan asli, dan substitusi, berada di bawah DocumentRoot (sebagai lawan dapat dijangkau dengan cara lain, seperti Alias).

  • Jalur sistem file ke direktori yang berisi RewriteRule, yang diakhiri dengan substitusi relatif juga valid sebagai jalur URL di server (ini jarang terjadi).

Seperti yang disebutkan sebelumnya, dalam konteks lain, akan berguna jika aturan Anda lebih pendek. Selain itu, seperti yang disebutkan sebelumnya, Anda dapat mencapai hal yang sama dengan menempatkan file htaccess di subdirektori.