Bagaimana cara kerja RewriteBase di .htaccess
Saya telah melihat ini dalam beberapa .htaccess
contoh
RewriteBase /
Tampaknya fungsinya agak mirip dengan <base href="">
HTML.
Saya percaya itu dapat secara otomatis menambahkan nilainya ke awal RewriteRule
pernyataan (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 RewriteRule
pernyataan saya .
Adakah yang bisa menjelaskan kepada saya secara singkat bagaimana menerapkannya?
Terima kasih
Jawaban
Dengan kata-kata saya sendiri, setelah membaca dokumen dan bereksperimen:
Anda dapat menggunakan RewriteBase
sebagai 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 RewriteBase
sana, Anda membuat jalur relatif keluar dari RewriteBase
parameter.
RewriteBase
hanya 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
Alias
arahanAnda 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 RewriteRule
relatif 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
) adalaha/b/c/d
. - Jika aturan ada
subdir2
dan permintaannya adalah/subdir2/e/f/g
URI yang diambil adalahe/f/g
. - Jika aturan ada di
subsubdir
, dan permintaannya ada/subdir2/subsubdir/x/y/z
, URI yang diambil adalahx/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.php
adalah jalur relatif, sebagai lawan dari:
RewriteRule ^foo$ /bar.php [L]
dimana /bar.php
adalah 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.php
Jalur 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 R
bendera, atau secara implisit karena Anda ada http://host
di 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 R
bendera, Anda akan berakhir mendapatkan diarahkan ke sesuatu seperti: http://example.com/var/www/localhost/htdocs/subdir1
. Yang jelas bukan yang Anda inginkan.
Di sinilah RewriteBase
masuk. 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/foo
akan 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/foo
akan berfungsi, http://example.com/subdir1/bar.php
dll. 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.
AFAIK, RewriteBase hanya digunakan untuk memperbaiki kasus di mana mod_rewrite berjalan di .htaccess
file 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/myfolder
Anda 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.
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.
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/
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.
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 /
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.