Ini adalah Pertanyaan Canonical tentang mod_rewrite Apache.
Mengubah URL permintaan atau mengarahkan pengguna ke URL yang berbeda dari yang mereka minta semula dilakukan menggunakan mod_rewrite. Ini termasuk hal-hal seperti:
- Mengubah HTTP ke HTTPS (atau sebaliknya)
- Mengubah permintaan ke halaman yang tidak ada lagi menjadi pengganti baru.
- Mengubah format URL (seperti? Id = 3433 ke / id / 3433)
- Menyajikan halaman berbeda berdasarkan browser, berdasarkan referensi, berdasarkan apa pun yang mungkin terjadi di bawah bulan dan matahari.
- Apa pun yang ingin Anda mainkan dengan URL
Semua yang Pernah Ingin Anda Ketahui tentang Aturan Mod_Rewrite tetapi Takut Bertanya!
Bagaimana saya bisa menjadi ahli dalam menulis aturan mod_rewrite?
- Apa format dan struktur mendasar dari aturan mod_rewrite?
- Apa bentuk / rasa dari ekspresi reguler yang perlu saya pahami?
- Apa kesalahan / jebakan paling umum saat menulis aturan penulisan ulang?
- Apa metode yang baik untuk menguji dan memverifikasi aturan mod_rewrite?
- Adakah implikasi SEO atau kinerja dari aturan mod_rewrite yang harus saya ketahui?
- Apakah ada situasi umum di mana mod_rewrite mungkin tampak seperti alat yang tepat untuk pekerjaan itu tetapi tidak?
- Apa saja contoh umum?
Tempat untuk menguji aturan Anda
Situs web penguji htaccess adalah tempat yang bagus untuk bermain-main dengan aturan Anda dan mengujinya. Bahkan menunjukkan hasil debug sehingga Anda dapat melihat apa yang cocok dan apa yang tidak.
apache-2.2
mod-rewrite
redirect
redirection
301-redirect
Kyle Brandt
sumber
sumber
mod-rewrite
pencarian tag / filter.Jawaban:
pesanan sintaks mod_rewrite
mod_rewrite memiliki beberapa aturan pemesanan khusus yang memengaruhi pemrosesan. Sebelum apa pun dilakukan,
RewriteEngine On
arahan perlu diberikan karena ini mengaktifkan pemrosesan mod_rewrite. Ini harus ada sebelum arahan penulisan ulang lainnya.RewriteCond
sebelumnyaRewriteRule
membuat bahwa SATU aturan tunduk pada persyaratan. Setiap RewriteRules berikut akan diproses seolah-olah mereka tidak tunduk pada persyaratan.Dalam kasus sederhana ini, jika pengarah HTTP berasal dari serverfault.com, arahkan kembali permintaan blog ke halaman khusus serverfault (kami hanya istimewa itu). Namun, jika blok di atas memiliki garis RewriteRule tambahan:
Semua file .jpg akan menuju ke halaman kesalahan server khusus, bukan hanya yang dengan perujuk yang menunjukkannya berasal dari sini. Ini jelas bukan maksud dari bagaimana aturan ini ditulis. Ini bisa dilakukan dengan beberapa aturan RewriteCond:
Tetapi mungkin harus dilakukan dengan beberapa sintaks pengganti yang lebih rumit.
RewriteRule yang lebih kompleks berisi persyaratan untuk diproses. Tanda kurung terakhir,
(html|jpg)
memberi tahu RewriteRule untuk mencocokkan salah satuhtml
ataujpg
, dan untuk mewakili string yang cocok sebagai $ 2 dalam string yang ditulis ulang. Ini secara logis identik dengan blok sebelumnya, dengan dua pasangan RewriteCond / RewriteRule, itu hanya dilakukan pada dua baris, bukan empat.Beberapa baris RewriteCond secara implisit ANDed, dan dapat secara eksplisit ORed. Untuk menangani referer dari ServerFault dan Pengguna Super (eksplisit ATAU):
Untuk melayani halaman yang dirujuk oleh ServerFault dengan browser Chrome (DAN implisit):
RewriteBase
juga dipesan khusus karena menentukan caraRewriteRule
arahan berikut menangani pemrosesan mereka. Ini sangat berguna dalam file .htaccess. Jika digunakan, itu harus menjadi arahan pertama di bawah "RewriteEngine on" dalam file .htaccess. Ambil contoh ini:Ini memberi tahu mod_rewrite bahwa URL khusus yang sedang ditangani tiba dengan cara http://example.com/blog/ alih-alih jalur direktori fisik (/ home / $ Username / public_html / blog) dan untuk memperlakukannya sesuai. Karena itu,
RewriteRule
anggap itu string-mulai setelah "/ blog" di URL. Berikut adalah hal yang sama ditulis dua cara berbeda. Satu dengan RewriteBase, yang lain tanpa:Seperti yang Anda lihat,
RewriteBase
memungkinkan penulisan ulang aturan untuk meningkatkan jalur situs web ke konten daripada server web , yang dapat membuatnya lebih mudah dipahami oleh mereka yang mengedit file tersebut. Juga, mereka dapat membuat arahan lebih pendek, yang memiliki daya tarik estetika.Sintaks yang cocok dengan RewriteRule
RewriteRule sendiri memiliki sintaks yang kompleks untuk string yang cocok. Saya akan menutupi bendera (hal-hal seperti [PT]) di bagian lain. Karena Sysadmin belajar dengan contoh lebih sering daripada dengan membaca halaman manual, saya akan memberikan contoh dan menjelaskan apa yang mereka lakukan.
The
.*
konstruk cocok dengan karakter tunggal (.
) nol atau lebih kali (*
). Melampirkannya di dalam tanda kurung menyuruhnya memberikan string yang cocok dengan variabel $ 1.Dalam hal ini, yang pertama. * TIDAK disertakan dalam parens sehingga tidak disediakan untuk string yang ditulis ulang. Aturan ini menghapus level direktori pada situs blog baru. (/blog/2009/sample.html menjadi /newblog/sample.html).
Dalam kasus ini, ekspresi kurung pertama mengatur grup yang cocok. Ini menjadi $ 1, yang tidak diperlukan dan karenanya tidak digunakan dalam string yang ditulis ulang.
Dalam hal ini, kami menggunakan $ 1 dalam string yang ditulis ulang.
Aturan ini menggunakan sintaks braket khusus yang menentukan rentang karakter . [0-9] cocok dengan angka 0 hingga 9. Aturan khusus ini akan menangani tahun dari 2000 hingga 2099.
Ini melakukan hal yang sama dengan aturan sebelumnya, tetapi bagian {2} mengatakannya untuk mencocokkan karakter sebelumnya (ekspresi kurung dalam kasus ini) dua kali.
Kasing ini akan cocok dengan huruf kecil apa pun dalam ekspresi pencocokan kedua, dan melakukannya untuk karakter sebanyak mungkin. The
\.
membangun mengatakan itu untuk mengobati periode sebagai periode yang sebenarnya, bukan karakter khusus itu di contoh sebelumnya. Akan rusak jika nama file memiliki tanda hubung di dalamnya.Ini menjebak nama file dengan tanda hubung di dalamnya. Namun, seperti
-
karakter khusus dalam ekspresi braket, itu harus menjadi karakter pertama dalam ekspresi.Versi ini menjebak nama file apa pun dengan huruf, angka atau
-
karakter dalam nama file. Ini adalah bagaimana Anda menentukan beberapa set karakter dalam ekspresi braket.Bendera RewriteRule
Bendera pada aturan penulisan ulang memiliki sejumlah makna dan penggunaan khusus .
Bendera adalah
[L]
di akhir ungkapan di atas. Beberapa bendera dapat digunakan, dipisahkan oleh koma. Dokumentasi tertaut menjelaskan masing-masing, tetapi di sini mereka tetap:L = Terakhir. Hentikan pemrosesan RewriteRules setelah ini cocok. Jumlah pesanan!
C = Rantai. Lanjutkan memproses RewriteRule berikutnya. Jika aturan ini tidak cocok, maka aturan selanjutnya tidak akan dieksekusi. Lebih lanjut tentang ini nanti.
E = Setel variabel lingkungan. Apache memiliki berbagai variabel lingkungan yang dapat memengaruhi perilaku server-web.
F = Dilarang. Mengembalikan kesalahan 403-Terlarang jika aturan ini cocok.
G = Pergi. Mengembalikan kesalahan 410-Gone jika aturan ini cocok.
H = Handler. Memaksa permintaan untuk ditangani seolah-olah itu adalah tipe MIME yang ditentukan.
N = Selanjutnya. Memaksa aturan untuk memulai kembali dan mencocokkan kembali. HATI-HATI! Pengulangan bisa terjadi.
NC = Tidak ada kasing. Memungkinkan
jpg
untuk mencocokkan jpg dan JPG.NE = Tidak ada jalan keluar. Mencegah penulisan ulang karakter khusus (.? # & Dll) ke dalam persamaan kode-heksnya.
NS = Tidak ada subrequest. Jika Anda menggunakan sisi-sisi-server, ini akan mencegah kecocokan dengan file yang disertakan.
P = Proxy. Memaksa aturan ditangani oleh mod_proxy. Secara transparan menyediakan konten dari server lain, karena server web Anda mengambilnya dan menyajikannya kembali. Ini adalah bendera yang berbahaya, karena yang ditulis dengan buruk akan mengubah server web Anda menjadi proxy-terbuka dan Itu Buruk.
PT = Lewati. Mempertimbangkan pernyataan Alias akun dalam pencocokan RewriteRule.
QSA = QSAppend. Saat string asli berisi kueri ( http://example.com/thing?asp=foo) menambahkan string kueri asli ke string yang ditulis ulang. Biasanya itu akan dibuang. Penting untuk konten dinamis.
R = Redirect. Berikan pengalihan HTTP ke URL yang ditentukan. Dapat juga memberikan kode redirect yang tepat [R = 303]. Sangat mirip
RedirectMatch
, yang lebih cepat dan harus digunakan jika memungkinkan.S = Lewati. Lewati aturan ini.
T = Jenis. Tentukan tipe pantomim dari konten yang dikembalikan. Sangat mirip dengan
AddType
arahan.Anda tahu bagaimana saya mengatakan itu
RewriteCond
berlaku untuk satu dan hanya satu aturan? Nah, Anda bisa menyiasatinya dengan merantai.Karena RewriteRule pertama memiliki flag Chain, aturan penulisan ulang kedua akan dieksekusi ketika yang pertama melakukannya, yaitu ketika aturan RewriteCond sebelumnya dicocokkan. Berguna jika ekspresi reguler Apache membuat otak Anda sakit. Namun, metode all-in-one-line yang saya tunjukkan di bagian pertama lebih cepat dari sudut pandang optimasi.
Ini dapat dibuat lebih sederhana melalui flag:
Juga, beberapa flag juga berlaku untuk RewriteCond. Khususnya, NoCase.
Akan cocok dengan "ServerFault.com"
sumber
mod_rewrite
Primer sangat bagus dan regex. +1.RewriteCond
sebenarnya diproses setelah yangRewriteRule
cocok. Anda mungkin ingin mengatakan "lebih lanjut tentang itu nanti" di dekat bagian atas di mana Anda mengatakan "RewriteCond sebelum RewriteRule membuat bahwa SATU aturan tunduk pada persyaratan." Anda mungkin ingin menyebutkan bahwa regex adalah ekspresi reguler yang kompatibel dengan Perl. Anda juga memiliki tanda kutip luar di "... the RewriteRule menganggap itu awal-string ..."RewriteRule ^/blog/.*/(.*)$ /newblog/$1
tidak cocok dengan komponen direktori pertama - penulisan ulang serakah secara default. /.*/(.*) cocok dengan / 1 / (2) / dan / 1/2/3/4/5 / (6) /, jadi Anda perlu / [^ /] * / hanya cocok dengan jalur FIRST komponen.Saya akan tunduk pada jawaban yang sangat baik dari sysadmin1138 tentang poin-poin ini.
Selain urutan sintaks, pencocokan sintaksis / ekspresi reguler, dan flag RewriteRule yang diuraikan oleh sysadmin1138, saya yakin itu menyebutkan bahwa mod_rewrite memperlihatkan variabel lingkungan Apache berdasarkan header permintaan HTTP dan konfigurasi Apache.
Saya akan merekomendasikan mod_rewrite Tutorial Debug AskApache untuk daftar variabel yang mungkin tersedia untuk mod_rewrite.
Sebagian besar masalah dengan batang RewriteRule berasal dari kesalahpahaman tentang sintaks / kegagalan PCRE untuk keluar dari karakter khusus dengan benar atau kurangnya wawasan tentang konten variabel yang digunakan untuk pencocokan.
Masalah umum dan pemecahan masalah yang disarankan:
IfModule
kondisi kondisional untuk menghindari skenario ini), periksa sintaks direktif, komentar arahan sampai komentar masalahPertama, lihat isi variabel lingkungan yang Anda rencanakan cocokkan - jika Anda memasang PHP, ini sesederhana menambahkan blok berikut ke aplikasi Anda:
... kemudian tulis aturan Anda (sebaiknya untuk pengujian pada server pengembangan) dan catat setiap pencocokan atau aktivitas yang tidak konsisten dalam file Apache ErrorLog Anda .
Untuk aturan yang lebih kompleks, gunakan
RewriteLog
arahan mod_rewrite untuk mencatat aktivitas ke file dan mengaturRewriteLogLevel 3
AllowOverride all
berdampak pada kinerja server karena Apache harus memeriksa.htaccess
file dan arahan parsing dengan setiap permintaan - jika memungkinkan, simpan semua arahan dalam konfigurasi VirtualHost untuk situs Anda atau aktifkan.htaccess
penggantian hanya untuk direktori yang membutuhkannya.Panduan Webmaster Google secara eksplisit menyatakan: "Jangan menipu pengguna Anda atau menyajikan konten yang berbeda untuk mesin pencari daripada yang Anda tampilkan kepada pengguna, yang biasanya disebut sebagai 'cloaking.'" - hindari membuat arahan mod_rewrite yang memfilter untuk robot mesin pencari.
Robot mesin pencari lebih suka konten 1: 1: Pemetaan URI (ini adalah dasar untuk menentukan peringkat tautan ke konten) - jika Anda menggunakan mod_rewrite untuk membuat pengalihan sementara atau Anda menyajikan konten yang sama di bawah beberapa URI, pertimbangkan untuk menentukan URI kanonik dalam dokumen HTML Anda.
Ini adalah topik besar (dan berpotensi kontroversial) dalam dirinya sendiri - lebih baik (IMHO) untuk mengatasi penggunaan berdasarkan kasus per kasus dan biarkan penanya menentukan apakah resolusi yang disarankan sesuai dengan kebutuhan mereka.
Mod_rewrite Trik dan Tip dari AskApache mencakup hampir semua kasus penggunaan umum yang muncul secara teratur, namun, solusi "yang benar" untuk pengguna tertentu dapat bergantung pada kecanggihan konfigurasi pengguna dan arahan yang ada (itulah sebabnya umumnya ide bagus untuk melihat arahan lain mana yang dimiliki pengguna setiap kali pertanyaan mod_rewrite muncul).
sumber
Redirect
atauRedirectMatch
sebagai gantinya. Lihat juga dokumen Apache: Kapan tidak menggunakan mod_rewriteSeperti banyak admin / pengembang lainnya, saya telah berjuang melawan seluk-beluk aturan penulisan ulang selama bertahun-tahun dan tidak senang dengan dokumentasi Apache yang ada, jadi saya memutuskan sebagai proyek pribadi untuk memahami bagaimana
mod_rewrite
sebenarnya bekerja dan berinteraksi dengan anggota Apache lainnya. inti, jadi selama beberapa bulan terakhir saya telah menginstruksikan kasus uji denganstrace
+ menelusuri kode sumber untuk menangani semua ini.Berikut adalah beberapa komentar kunci yang perlu dipertimbangkan pengembang menulis ulang:
.htaccess
pemrosesan PerDir ( ).Saya ingin mengatakan bahwa karena ini Anda hampir perlu membagi komunitas pengguna yang menulis ulang menjadi dua kategori dan memperlakukannya sebagai sepenuhnya terpisah:
Mereka yang memiliki akses root ke konfigurasi Apache . Ini biasanya admin / pengembang dengan aplikasi dedicated server / VM, dan pesan di sini cukup sederhana: hindari menggunakan
.htaccess
file jika memungkinkan; lakukan semua yang ada di server atau konfigurasi vhost. Debugging itu wajar mudah karena pengembang dapat mengatur debugging dan memiliki akses ke file rewrite.log.Pengguna layanan yang dihosting bersama (SHS) .
.htaccess
pemrosesan / Perdir karena tidak ada alternatif yang tersedia..htaccess
file PerDir apa yang dipilih dan mengapa. Ini tidak menjelaskan seluk beluk siklus PerDir dan bagaimana menghindarinya.Mungkin ada komunitas ketiga: admin dan staf pendukung di penyedia SHS yang berakhir dengan berjalan kaki di kedua kubu dan harus menanggung konsekuensi dari hal di atas.
Saya telah menulis beberapa posting blog bergaya artikel (mis. Lebih lanjut tentang penggunaan aturan Tulis Ulang dalam file .htaccess ) yang mencakup banyak poin rinci yang tidak akan saya ulangi di sini untuk membuat posting ini singkat. Saya memiliki layanan bersama saya sendiri serta mendukung beberapa proyek FLOSS berdedikasi & VM. Saya mulai menggunakan LAMP VM standar sebagai kendaraan uji untuk akun SHS saya, tetapi pada akhirnya saya merasa lebih baik untuk melakukan mirror VM yang tepat (dijelaskan di sini ).
Namun, dalam hal bagaimana komunitas admin harus mendukung
.htaccess
pengguna, saya merasa bahwa kami perlu mengembangkan dan menawarkan:.htaccess
aturan penulisan ulangPetunjuk tentang cara mendapatkan diagnostik bawaan dari aturan Anda (mis
[E=VAR:EXPR]
mengeksploitasi fakta yangEXPR
akan memperluas referensi-kembali ($ N atau% N) untuk membuatnya tersedia sebagai diagnostik untuk skrip target.Jika Anda memesan aturan penulisan ulang secara topikal menggunakan tanda [OR], [C], [SKIP] dan [L] sehingga seluruh skema penulisan ulang berfungsi tanpa perlu mengeksploitasi pengalihan internal, maka Anda dapat menambahkan yang berikut sebagai aturan 1 untuk menghindari semua kerumitan perulangan:
sumber
.htaccess
topik dan Anda akan melihat. Kebanyakan pemula menjadi sangat putus asa - kebanyakan dari mereka memiliki pengalaman pertama mereka dari layanan LAMP dan mod_rewrite pada layanan bersama dan oleh karena itu tidak memiliki akses root ke konfigurasi sistem / vhost dan harus menggunakan pemrosesan langsung melalui.htaccess
file. Ada perbedaan penting yang harus "dikuasai" oleh pemula. Saya akan menganggap diri saya sebagai pengguna daya dan saya masih menemukan seluk-beluk. Seperti yang saya katakan, saya harus menggunakan pemindaian strace dan kode sumber untuk mengetahui beberapa aspek. Tidak perlu. :-(.htaccess
, yang sangat rapuh, rumit, dan membingungkan, bahkan untuk para ahli. Saya MASIH mengalami masalah.Menggunakan peta ulang
Ada banyak hal yang dapat Anda lakukan dengan penulisan ulang peta. Rewritemaps dideklarasikan menggunakan direktif Rewritemap, dan kemudian dapat digunakan baik dalam evaluasi RewritCond, dan dalam Subsitutions RewriteRule.
Sintaks umum untuk RewriteMap adalah:
Sebagai contoh:
Anda kemudian dapat menggunakan mapname untuk konstruksi seperti ini:
Peta berisi pasangan kunci / nilai. Jika kunci ditemukan, nilainya diganti. Peta sederhana hanyalah file teks biasa, tetapi Anda dapat menggunakan peta hash, dan bahkan query SQL. Lebih detail ada di dokumen:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap
Unescaping string.
Ada empat peta internal yang dapat Anda gunakan untuk melakukan manipulasi. Terutama string unescaping bisa berguna.
Misalnya: Saya ingin menguji string "café" di string kueri. Namun, browser akan lolos dari ini sebelum mengirimkannya ke server saya, jadi saya perlu mencari tahu apa URL yang lolos dari versi untuk setiap string yang ingin saya cocokkan, atau saya hanya dapat menghapusnya ...
Perhatikan bagaimana saya menggunakan satu RewriteCond untuk menangkap argumen di bawah parameter string kueri, dan kemudian gunakan peta di rewriteCond kedua untuk menghapusnya. Ini kemudian dibandingkan. Perhatikan juga bagaimana saya perlu kita% 2 sebagai kunci dalam rewritemap, karena% 1 akan mengandung "lokasi" atau "tempat". Saat Anda menggunakan tanda kurung untuk mengelompokkan pola mereka juga akan ditangkap, apakah Anda berencana untuk menggunakan hasil penangkapan atau tidak ...
sumber
mod_rewrite
regexp mendukung kelompok yang tidak menangkap seperti(?:location|place)
dan ini hanya akan memiliki satu tangkapan dalam contoh.Jebakan yang sangat mudah adalah ketika Anda menulis ulang URL yang mengubah jalur yang terlihat, misalnya dari
/base/1234/index.html
menjadi/base/script.php?id=1234
. Gambar atau CSS apa pun dengan jalur relatif ke lokasi skrip tidak akan ditemukan oleh klien. Sejumlah opsi untuk menyelesaikan ini dapat ditemukan pada faq ini .sumber
<base>
tag yang paling mudah diikuti dan masih memungkinkan jalur relatif.