Tampaknya ada sejumlah mod_rewrite
utas yang beredar belakangan ini dengan sedikit kebingungan tentang bagaimana aspek-aspek tertentu bekerja. Sebagai hasilnya saya telah mengumpulkan beberapa catatan tentang fungsionalitas umum, dan mungkin beberapa nuansa yang mengganggu.
Apa fitur / masalah umum lain yang pernah Anda temui mod_rewrite
?
apache
.htaccess
mod-rewrite
Owen
sumber
sumber
Jawaban:
Di mana harus menempatkan aturan mod_rewrite
mod_rewrite
aturan dapat ditempatkan di dalamhttpd.conf
file, atau di dalam.htaccess
file. jika Anda memiliki akses kehttpd.conf
, menempatkan aturan di sini akan menawarkan manfaat kinerja (karena aturan diproses sekali, berbeda dengan setiap kali.htaccess
file dipanggil).Mencatat permintaan mod_rewrite
Logging dapat diaktifkan dari dalam
httpd.conf
file (termasuk<Virtual Host>
):Kasus penggunaan umum
Untuk menyalurkan semua permintaan ke satu titik:
Sejak Apache 2.2.16 Anda juga dapat menggunakan
FallbackResource
.Menangani pengalihan 301/302:
Catatan : pengalihan eksternal secara implisit adalah 302 pengalihan:
Memaksa SSL
Bendera umum:
[R]
atau[redirect]
- paksa pengalihan (default ke pengalihan sementara 302)[R=301]
atau[redirect=301]
- memaksa pengalihan permanen 301[L]
atau[last]
- hentikan proses penulisan ulang (lihat catatan di bawah ini untuk kesalahan umum)[NC]
atau[nocase]
- tentukan bahwa pencocokan harus peka huruf besar / kecilMenggunakan tanda berbentuk panjang seringkali lebih mudah dibaca dan akan membantu orang lain yang datang untuk membaca kode Anda nanti.
Anda dapat memisahkan beberapa bendera dengan koma:
Jebakan umum
mod_alias
Pengalihan gaya pencampuran denganmod_rewrite
Catatan : Anda dapat mencampur
mod_alias
denganmod_rewrite
, tetapi melibatkan lebih banyak pekerjaan dari sekedar penanganan pengalihan dasar seperti di atas.Konteks memengaruhi sintaks
Di dalam
.htaccess
file, garis miring di depan tidak digunakan dalam pola RewriteRule:[L] bukan yang terakhir! (terkadang)
The
[L]
bendera berhenti memproses aturan menulis ulang lebih lanjut untuk itu melewati peraturan yang ditetapkan . Namun, jika URL telah diubah di pass itu dan Anda berada dalam.htaccess
konteks atau<Directory>
bagian, maka permintaan Anda yang dimodifikasi akan diteruskan kembali melalui mesin pengurai URL lagi. Dan pada umpan berikutnya, kali ini mungkin cocok dengan aturan yang berbeda. Jika Anda tidak memahami hal ini, seringkali[L]
benderanya tampak tidak berpengaruh.Log penulisan ulang kami menunjukkan bahwa aturan dijalankan dua kali dan URL diperbarui dua kali:
Cara terbaik untuk menyiasatinya adalah dengan menggunakan
[END]
flag ( lihat dokumen Apache ) daripada menggunakan[L]
flag, jika Anda benar-benar ingin menghentikan semua pemrosesan aturan lebih lanjut (dan penerusan berikutnya). Namun,[END]
flag tersebut hanya tersedia untuk Apache v2.3.9 + , jadi jika Anda memiliki v2.2 atau lebih rendah, Anda tidak dapat lagi menggunakan[L]
flag tersebut.Untuk versi sebelumnya, Anda harus bergantung pada
RewriteCond
pernyataan untuk mencegah pencocokan aturan pada penerusan berikutnya dari mesin pengurai URL.Atau Anda harus memastikan bahwa RewriteRule Anda berada dalam konteks (yaitu
httpd.conf
) yang tidak akan menyebabkan permintaan Anda diurai ulang.sumber
[L]
bendera berarti aturan adalah terakhir dalam pengolahan saat ini, ini tidak akan berhenti menulis ulang, karena mereka adalah pengalihan internal, sehingga AndadirB
berlaku untukdirC
dalam pengolahan htaccess berikutnya. SendiriRewriteRule ^(.*)$ index.php?query=$1
akan menjadi loop pengalihan internal tak terbatas (dalam praktiknya dihentikan setelah 10 iterasi). -1 karena Anda menyarankan bahwa [L] bukan yang terakhir . Ini tidak menghentikan proses penulisan ulang, tetapi ini yang terakhir .RewriteCond %{HTTPS} off
adalah cara yang disukai untuk memeriksa koneksi HTTPS (dalam contoh Anda memaksa lalu lintas non-ssl ke HTTPS)jika Anda perlu 'memblokir' pengalihan / penulisan ulang internal agar tidak terjadi di .htaccess, lihat
kondisi, seperti yang dibahas di sini .
sumber
.*
dengan[L]
bendera yang saya baca sebelum saya sampai di sini.200
,!=200
,^.
,^$
. Tampaknya variabel disetel ke200
untuk pengalihan, tetapi juga halaman lain (kesalahan dan hal-hal) menyetelnya ke beberapa nilai. Sekarang berarti bahwa Anda juga memeriksa apakah ituis empty
,is not empty
,is 200
atauis not 200
, tergantung pada apa yang Anda butuhkan.Kesepakatan dengan RewriteBase:
Anda hampir selalu perlu menyetel RewriteBase. Jika tidak, apache menebak bahwa basis Anda adalah jalur disk fisik ke direktori Anda. Jadi mulailah dengan ini:
sumber
RewriteBase .
, atau sesuatu untuk menunjukkan bahwa itu harus menjaga URL tetap sama, hanya mengubah apa yang telah Anda tentukan?RewriteBase
jika Anda menggunakan substitusi jalur relatif dalamRewriteRule
direktif. Lebih baik hindari menggunakan jalur relatif.RewriteBase
sama sekali karena hampir semua pengembang salah paham tentang fungsinya. Seperti yang dikatakan @ w3d, Anda hanya membutuhkannya jika Anda ingin menyimpan karakter dan ingin menerapkan basis yang sama ke semua RewriteRules Anda dalam satu file. Kode Anda kemungkinan akan lebih jelas bagi orang lain jika Anda menghindarinya.Jebakan Lainnya:
1- Terkadang ide yang bagus untuk menonaktifkan MultiView
Saya kurang paham tentang semua kemampuan MultiView, tetapi saya tahu bahwa ini mengacaukan aturan mod_rewrite saya saat aktif, karena salah satu propertinya adalah mencoba dan 'menebak' ekstensi ke file yang menurutnya sedang saya cari .
Saya akan menjelaskan: Misalkan Anda memiliki 2 file php di dir web Anda, file1.php dan file2.php dan Anda menambahkan ketentuan dan aturan ini ke .htaccess Anda:
Anda berasumsi bahwa semua url yang tidak cocok dengan file atau direktori akan diambil oleh file1.php. Mengherankan! Aturan ini tidak diterapkan untuk url http: // myhost / file2 / somepath . Sebaliknya Anda dibawa ke dalam file2.php.
Apa yang terjadi adalah MultiView secara otomatis menebak bahwa url yang sebenarnya Anda inginkan adalah http: //myhost/file2.php/somepath dan dengan senang hati membawa Anda ke sana.
Sekarang, Anda tidak tahu apa yang baru saja terjadi dan Anda pada saat itu mempertanyakan semua yang Anda pikir Anda ketahui tentang mod_rewrite. Anda kemudian mulai bermain-main dengan aturan untuk mencoba memahami logika di balik situasi baru ini, tetapi semakin Anda menguji semakin tidak masuk akal.
Ok, Singkatnya jika Anda ingin mod_rewrite bekerja dengan cara yang mendekati logika, mematikan MultiView adalah langkah yang tepat.
2- Aktifkan FollowSymlinks
Yang itu, saya tidak begitu tahu detailnya, tapi saya sudah sering melihatnya disebutkan, jadi lakukan saja.
sumber
+FollowSymLinks
disebutkan dalam dokumentasi sebagai wajib untukmod_rewrite
bekerja sama sekali, untuk alasan keamanan yang tidak jelas.Persamaan dapat dilakukan dengan contoh berikut:
Penyeimbangan Beban Dinamis:
Jika Anda menggunakan mod_proxy untuk menyeimbangkan sistem Anda, dimungkinkan untuk menambahkan rentang dinamis server pekerja.
sumber
Pemahaman yang lebih baik tentang bendera [L] sudah beres. Bendera [L] adalah yang terakhir, Anda hanya perlu memahami apa yang akan menyebabkan permintaan Anda dirutekan lagi melalui mesin parsing URL. Dari dokumen ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (penekanan milik saya):
Jadi [L] Bendera tidak berhenti memproses aturan menulis ulang lebih lanjut untuk yang lulus melalui set aturan. Namun, jika aturan Anda yang ditandai dengan [L] mengubah permintaan tersebut, dan Anda berada dalam konteks .htaccess atau
<Directory>
bagian tersebut, maka permintaan yang telah diubah tersebut akan diteruskan kembali melalui mesin pengurai URL lagi. Dan pada umpan berikutnya, kali ini mungkin cocok dengan aturan yang berbeda. Jika Anda tidak mengerti apa yang terjadi, sepertinya aturan penulisan ulang pertama Anda dengan bendera [L] tidak berpengaruh.Cara terbaik untuk menyiasatinya adalah dengan menggunakan flag [AKH] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) alih-alih flag [L], jika Anda benar-benar ingin berhenti semua pemrosesan aturan lebih lanjut (dan penguraian ulang berikutnya). Akan tetapi, flag [END] hanya tersedia untuk Apache v2.3.9 +, jadi jika Anda memiliki v2.2 atau lebih rendah, Anda tidak bisa lagi menggunakan flag [L]. Dalam kasus ini, Anda harus mengandalkan pernyataan RewriteCond untuk mencegah pencocokan aturan pada proses berikutnya dari mesin parsing URL. Atau Anda harus memastikan bahwa RewriteRule Anda berada dalam konteks (mis. Httpd.conf) yang tidak akan menyebabkan permintaan Anda diurai ulang.
sumber
Fitur hebat lainnya adalah rewrite-map-expansions. Mereka sangat berguna jika Anda memiliki banyak host / penulisan ulang untuk ditangani:
Mereka seperti pengganti nilai kunci:
Kemudian Anda dapat menggunakan pemetaan dalam aturan Anda seperti:
Informasi lebih lanjut tentang topik ini dapat ditemukan di sini:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
sumber
.htaccess
penulisan ulang berbasis. Itu tidak bekerja dalam konteks ini.mod_rewrite dapat memodifikasi aspek penanganan permintaan tanpa mengubah URL, misalnya mengatur variabel lingkungan, mengatur cookie, dll. Ini sangat berguna.
Tetapkan variabel lingkungan secara bersyarat:
Kembali respon 503:
RewriteRule
's[R]
bendera dapat mengambil nilai non-3xx dan kembali respon non-mengarahkan, misalnya untuk dikelola downtime / pemeliharaan:akan mengembalikan respons 503 (bukan pengalihan per se).
Selain itu, mod_rewrite dapat bertindak seperti antarmuka bertenaga super untuk mod_proxy, jadi Anda dapat melakukan ini alih-alih menulis
ProxyPass
arahan:Opini: Menggunakan
RewriteRule
s danRewriteCond
s untuk merutekan permintaan ke aplikasi atau penyeimbang beban yang berbeda berdasarkan hampir semua aspek permintaan yang mungkin sangat kuat. Mengontrol permintaan dalam perjalanannya ke backend, dan dapat mengubah tanggapan saat keluar, menjadikan mod_rewrite tempat yang ideal untuk memusatkan semua konfigurasi yang terkait dengan perutean.Luangkan waktu untuk mempelajarinya, itu sangat berharga! :)
sumber