"Tautan cantik" adalah topik yang sering diminta, tetapi jarang dijelaskan sepenuhnya. mod_rewrite adalah salah satu cara untuk membuat "tautan yang cantik", tetapi kompleks dan sintaksisnya sangat singkat, sulit untuk grok, dan dokumentasi mengasumsikan tingkat kemahiran HTTP tertentu. Dapatkah seseorang menjelaskan secara sederhana bagaimana "tautan cantik" bekerja dan bagaimana mod_rewrite dapat digunakan untuk membuatnya?
Nama umum lainnya, alias, istilah untuk URL bersih: URL tenang , URL yang mudah digunakan, URL SEO -friendly , slugging , dan URL MVC (mungkin salah nama)
apache
.htaccess
mod-rewrite
friendly-url
tipuan
sumber
sumber
reference-mod-rewrite-url-rewriting-explained
juga siput,/questions/20563772/reference-mod-rewrite-url-rewriting-explained
adalah URL yang cantik..htaccess
danmod-rewrite
harus diperbarui untuk menyertakan tautan ke pertanyaan ini, karena mencakup banyak dari apa yang ditanyakan secara teratur. Pikiran?Jawaban:
Untuk memahami apa yang mod_rewrite lakukan, pertama-tama Anda perlu memahami cara kerja server web. Server web merespons permintaan HTTP . Permintaan HTTP di tingkat paling dasar terlihat seperti ini:
Ini adalah permintaan sederhana dari browser ke server web yang meminta URL
/foo/bar.html
darinya. Penting untuk ditekankan bahwa itu tidak meminta file , hanya meminta beberapa URL sewenang-wenang. Permintaan juga dapat terlihat seperti ini:Ini sama validnya dengan permintaan untuk URL, dan jelas tidak ada hubungannya dengan file.
Server web adalah aplikasi yang mendengarkan pada port, menerima permintaan HTTP yang masuk pada port itu dan mengembalikan respons. Server web sepenuhnya bebas untuk menanggapi permintaan apa pun yang menurutnya sesuai / dengan cara apa pun yang telah Anda konfigurasikan untuk merespons. Respons ini bukan file, ini respons HTTP yang mungkin atau mungkin tidak ada hubungannya dengan file fisik pada disk apa pun. Server web tidak harus Apache, ada banyak server web lain yang semuanya hanya program yang berjalan terus-menerus dan dilampirkan ke port yang merespons permintaan HTTP. Anda dapat menulis sendiri. Paragraf ini dimaksudkan untuk menceraikan Anda dari anggapan bahwa URL secara langsung menyamakan file, yang sangat penting untuk dipahami. :)
Konfigurasi default sebagian besar server web adalah mencari file yang cocok dengan URL pada hard disk. Jika akar dokumen server diatur ke, katakanlah,
/var/www
mungkin terlihat apakah file tersebut/var/www/foo/bar.html
ada dan sajikan jika demikian. Jika file berakhir dengan ".php" itu akan memanggil penerjemah PHP dan kemudian mengembalikan hasilnya. Semua asosiasi ini sepenuhnya dapat dikonfigurasi; file tidak harus diakhiri dengan ".php" agar server web dapat menjalankannya melalui penerjemah PHP, dan URL tidak harus mencocokkan file tertentu pada disk untuk sesuatu terjadi.mod_rewrite adalah cara untuk menulis ulang penanganan permintaan internal. Ketika server web menerima permintaan untuk URL
/foo/bar
, Anda dapat menulis ulang URL itu menjadi sesuatu yang lain sebelum server web akan mencari file pada disk untuk mencocokkannya. Contoh sederhana:Aturan ini mengatakan kapan saja permintaan cocok dengan "/ foo / bar", tulis ulang menjadi "/ foo / baz". Permintaan kemudian akan ditangani seolah-olah
/foo/baz
telah diminta sebagai gantinya. Ini dapat digunakan untuk berbagai efek, misalnya:Aturan ini cocok dengan apa pun (
.*
) dan menangkapnya ((..)
), lalu menulis ulang untuk menambahkan ".html". Dengan kata lain, jika/foo/bar
URL yang diminta, itu akan ditangani seolah-olah/foo/bar.html
telah diminta. Lihat http://regular-expressions.info untuk informasi lebih lanjut tentang pencocokan ekspresi reguler, penangkapan, dan penggantian.Aturan lain yang sering ditemui adalah ini:
Ini, sekali lagi, cocok dengan apa pun dan menulis ulang ke file index.php dengan URL yang awalnya diminta ditambahkan dalam
url
parameter kueri. Yaitu, untuk setiap dan semua permintaan yang masuk, file index.php dieksekusi dan file ini akan memiliki akses ke permintaan asli$_GET['url']
, sehingga dapat melakukan apa pun yang diinginkan.Terutama Anda memasukkan aturan penulisan ulang ini ke file konfigurasi server web Anda . Apache juga memungkinkan Anda untuk meletakkannya di file yang disebut di
.htaccess
dalam root dokumen Anda (yaitu di sebelah file .php Anda).* Jika diizinkan oleh file konfigurasi Apache utama; itu opsional, tetapi sering diaktifkan.
Apa yang tidak dilakukan mod_rewrite
mod_rewrite tidak secara ajaib membuat semua URL Anda "cantik". Ini adalah kesalahpahaman umum. Jika Anda memiliki tautan ini di situs web Anda:
tidak ada yang bisa dilakukan mod_rewrite untuk membuatnya cantik. Untuk menjadikan ini tautan yang cantik, Anda harus:
Ubah tautan ke tautan yang cantik:
Gunakan mod_rewrite di server untuk menangani permintaan ke URL
/my/pretty/link
menggunakan salah satu metode yang dijelaskan di atas.(Orang dapat menggunakan
mod_substitute
bersama-sama untuk mengubah halaman HTML keluar dan tautannya yang terkandung. Meskipun ini biasanya lebih banyak upaya daripada hanya memperbarui sumber daya HTML Anda.)Ada banyak yang dapat dilakukan mod_rewrite dan aturan pencocokan yang sangat rumit yang dapat Anda buat, termasuk merantai beberapa penulisan ulang, memproksi permintaan ke layanan atau mesin yang sama sekali berbeda, mengembalikan kode status HTTP tertentu sebagai tanggapan, mengarahkan permintaan, dll. Ini sangat kuat dan dapat digunakan untuk Sangat bagus jika Anda memahami mekanisme permintaan-respons HTTP mendasar. Itu tidak secara otomatis membuat tautan Anda cantik.
Lihat dokumentasi resmi untuk semua kemungkinan bendera dan opsi.
sumber
Untuk memperluas jawaban tipuan , saya ingin memberikan beberapa contoh dan penjelasan tentang beberapa fungsi mod_rewrite lainnya.
Semua contoh di bawah ini mengasumsikan bahwa Anda sudah termasuk
RewriteEngine On
dalam.htaccess
file Anda .Tulis ulang Contoh
Mari kita ambil contoh ini:
Aturan dibagi menjadi 4 bagian:
RewriteRule
- memulai aturan penulisan ulang^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
- Ini disebut polanya, namun saya hanya akan menyebutnya sebagai sisi kiri dari aturan - apa yang ingin Anda tulis ulang dariblog/index.php?id=$1&title=$2
- Disebut substitusi, atau sisi kanan aturan penulisan ulang - apa yang ingin Anda tulis ulang[NC,L,QSA]
adalah bendera untuk aturan penulisan ulang, dipisahkan oleh koma, yang akan saya jelaskan lebih lanjut nantiPenulisan ulang di atas akan memungkinkan Anda untuk menautkan ke sesuatu seperti
/blog/1/foo/
dan itu benar-benar akan memuat/blog/index.php?id=1&title=foo
.Sisi kiri aturan
^
menunjukkan awal nama halaman - jadi itu akan menulis ulangexample.com/blog/...
tetapi tidakexample.com/foo/blog/...
(…)
tanda kurung menunjukkan ekspresi reguler yang dapat kita tangkap sebagai variabel di sisi kanan aturan. Dalam contoh ini:([0-9]+)
- cocok dengan string dengan panjang minimal 1 karakter dan hanya dengan nilai numerik (yaitu 0-9). Ini dapat dirujuk dengan$1
di sisi kanan aturan-
atau+
(catatan+
lolos dengan backslash karena tanpa melarikan diri itu akan dijalankan sebagai regex karakter pengulangan ). Ini dapat dirujuk dengan$2
di sisi kanan aturan?
berarti karakter sebelumnya adalah opsional, jadi dalam hal ini keduanya/blog/1/foo/
dan/blog/1/foo
akan menulis ulang ke tempat yang sama$
menunjukkan ini adalah akhir dari string yang ingin kita cocokkanBendera
Ini adalah opsi yang ditambahkan dalam tanda kurung di akhir aturan penulisan ulang Anda untuk menentukan kondisi tertentu. Sekali lagi, ada banyak flag berbeda yang dapat Anda baca di dokumentasi , tetapi saya akan membaca beberapa flag yang lebih umum:
Bendera tanpa huruf besar berarti aturan penulisan ulang tidak sensitif huruf besar, jadi untuk contoh aturan di atas ini berarti keduanya
/blog/1/foo/
dan/BLOG/1/foo/
(atau variasi apa pun dari ini) akan cocok.Bendera terakhir menunjukkan bahwa ini adalah aturan terakhir yang harus diproses. Ini berarti bahwa jika dan hanya jika aturan ini cocok, tidak ada aturan lebih lanjut yang akan dievaluasi dalam proses pemrosesan penulisan ulang saat ini. Jika aturan tidak cocok, semua aturan lainnya akan dicoba berurutan seperti biasa. Jika Anda tidak mengatur
L
benderanya, semua aturan berikut akan diterapkan ke URL yang ditulis ulang sesudahnya.Karena Apache 2.4 Anda juga dapat menggunakan
[END]
flag. Aturan yang cocok dengannya akan sepenuhnya menghentikan pemrosesan alias / penulisan ulang lebih lanjut. (Bahwa[L]
bendera seringkali dapat memicu putaran kedua, misalnya ketika menulis ulang masuk atau keluar dari subdirektori.)Bendera append string string memungkinkan kita untuk mengirimkan variabel tambahan ke URL yang ditentukan yang akan ditambahkan ke parameter get asli. Sebagai contoh kita ini berarti sesuatu seperti
/blog/1/foo/?comments=15
akan dimuat/blog/index.php?id=1&title=foo&comments=15
Bendera ini bukan yang saya gunakan dalam contoh di atas, tetapi bendera yang menurut saya layak disebutkan. Ini memungkinkan Anda untuk menentukan pengalihan http, dengan opsi untuk memasukkan kode status (misalnya
R=301
). Sebagai contoh jika Anda ingin melakukan pengalihan 301 di / myblog / ke / blog / Anda cukup menulis aturan seperti ini:Kondisi Penulisan Ulang
Kondisi penulisan ulang membuat penulisan ulang menjadi lebih kuat, memungkinkan Anda menentukan penulisan ulang untuk situasi yang lebih spesifik. Ada banyak kondisi yang dapat Anda baca di dokumentasi , tetapi saya akan menyentuh beberapa contoh umum dan menjelaskannya:
Ini adalah praktik yang sangat umum, yang akan menambah dengan domain Anda
www.
(jika belum ada di sana) dan menjalankan pengalihan 301. Misalnya, memuatnyahttp://example.com/blog/
akan mengarahkan Anda kehttp://www.example.com/blog/
Ini sedikit kurang umum, tetapi merupakan contoh yang baik dari aturan yang tidak dijalankan jika nama file adalah direktori atau file yang ada di server.
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
hanya akan menjalankan penulisan ulang untuk file dengan ekstensi file jpg, jpeg, gif atau png (case-sensitive).%{REQUEST_FILENAME} !-f
akan memeriksa untuk melihat apakah file ada di server saat ini, dan hanya menjalankan penulisan ulang jika tidak%{REQUEST_FILENAME} !-d
akan memeriksa untuk melihat apakah file ada di server saat ini, dan hanya menjalankan penulisan ulang jika tidaksumber
Referensi
Stack Overflow memiliki banyak sumber daya hebat lainnya untuk memulai:
(Perlu diingat untuk menghapus
^/
awalan pola slash in untuk.htaccess
penggunaan.)Dan bahkan gambaran umum regex ramah baru:
Placeholder bekas pakai
.*
cocok dengan apa pun, bahkan string kosong. Anda tidak ingin menggunakan pola ini di mana-mana, tetapi sering kali dalam aturan fallback terakhir.[^/]+
lebih sering digunakan untuk segmen jalur. Ini cocok dengan apa pun kecuali garis miring.\d+
hanya cocok dengan string numerik.\w+
cocok dengan karakter alfanumerik. Ini pada dasarnya singkatan[A-Za-z0-9_]
.[\w\-]+
untuk segmen jalur gaya "slug", menggunakan huruf, angka, tanda hubung-
dan_
[\w\-.,]+
menambahkan titik dan koma. Lebih suka\-
lari kabur di[…]
charclass.\.
menunjukkan periode literal. Kalau tidak, di.
luar[…]
adalah placeholder untuk simbol apa pun.Masing-masing penampung ini biasanya dibungkus dengan
(…)
tanda kurung sebagai kelompok tangkap. Dan seluruh pola sering di^………$
spidol awal + akhir. Mengutip "pola" adalah opsional.RewriteRules
Contoh-contoh berikut adalah PHP-centric dan sedikit lebih inkremental, lebih mudah diadaptasi untuk kasus serupa. Itu hanya ringkasan, sering menautkan ke lebih banyak variasi atau tanya jawab secara terperinci.
Pemetaan statis
/contact
,/about
Memendekkan beberapa nama halaman menjadi skema file internal adalah yang paling sederhana:
Pengidentifikasi numerik
/object/123
Memperkenalkan cara pintas seperti
http://example.com/article/531
ke skrip PHP yang ada juga mudah. Tempat penampung angka hanya dapat dipetakan kembali ke$_GET
parameter:Penampung gaya-siput
/article/with-some-title-slug
Anda dapat dengan mudah memperluas aturan itu untuk memungkinkan
/article/title-string
placeholder:Perhatikan bahwa skrip Anda harus dapat (atau disesuaikan) untuk memetakan judul-judul itu kembali ke id-database. RewriteRules saja tidak dapat membuat atau menebak informasi dari udara kosong.
Siput dengan awalan angka
/readable/123-plus-title
Karenanya Anda akan sering melihat
/article/529-title-slug
jalur campuran yang digunakan dalam praktik:Sekarang Anda bisa melewatkan melewati
title=$2
saja, karena skrip Anda biasanya akan bergantung pada database-id. The-title-slug
telah menjadi dekorasi URL sewenang-wenang.Keseragaman dengan daftar alternatif
/foo/…
/bar/…
/baz/…
Jika Anda memiliki aturan serupa untuk beberapa jalur halaman virtual, maka Anda dapat mencocokkan dan memadatkannya dengan
|
daftar alternatif. Dan lagi, tetapkan kembali ke parameter GET internal:Anda dapat membaginya menjadi individu
RewriteRule
jika ini menjadi terlalu kompleks.Mengirim URL terkait ke berbagai backend
/date/SWITCH/backend
Penggunaan daftar alternatif yang lebih praktis adalah memetakan jalur permintaan ke skrip yang berbeda. Misalnya untuk memberikan URL yang seragam untuk aplikasi web yang lebih lama dan lebih baru berdasarkan tanggal:
Ini hanya memetakan ulang 2009-2011 posting ke satu skrip, dan semua tahun lainnya secara implisit ke penangan lain. Perhatikan aturan yang lebih spesifik lebih dulu . Setiap skrip mungkin menggunakan paret GET yang berbeda.
Pembatas lain dari sekadar
/
garis miring/user-123-name
Anda paling sering melihat RewriteRules untuk mensimulasikan struktur direktori virtual. Tetapi Anda tidak dipaksa untuk tidak kreatif. Anda juga bisa menggunakan
-
tanda hubung untuk segmentasi atau struktur.Untuk
/wiki:section:Page_Name
skema yang juga umum :Kadang-kadang itu cocok untuk bergantian antara
/
-delimiters dan:
atau.
dalam aturan yang sama bahkan. Atau minta dua RewriteRules lagi untuk memetakan varian ke skrip yang berbeda.Opsional
/
garis miring slash/dir
=/dir/
Saat memilih jalur gaya direktori, Anda dapat membuatnya dapat dicapai dengan dan tanpa final /
Sekarang ini menangani keduanya
http://example.com/blog/123
dan/blog/123/
. Dan/?$
pendekatannya mudah ditambahkan ke aturan RewriteR lainnya.Segmen fleksibel untuk jalur virtual
.*/.*/.*/.*
Sebagian besar aturan yang Anda temui akan memetakan sekumpulan
/…/
segmen jalur sumber daya yang dibatasi ke parameter GET individual. Beberapa skrip menangani sejumlah opsi variabel . Mesin regexp Apache tidak memungkinkan untuk memilih jumlah yang sewenang-wenang dari mereka. Tetapi Anda dapat dengan mudah mengembangkannya menjadi aturan yang memblokir diri Anda sendiri:Jika Anda memerlukan hingga lima segmen jalur, salin skema ini ke dalam lima aturan. Anda tentu saja dapat menggunakan yang lebih spesifik
[^/]+
masing-masing placeholder yang . Di sini pemesanan tidak begitu penting, karena tidak ada yang tumpang tindih. Jadi memiliki jalur yang paling sering digunakan pertama kali tidak apa-apa.Atau Anda dapat menggunakan parameter array PHP melalui
?p[]=$1&p[]=$2&p[]=3
string kueri di sini - jika skrip Anda hanya menginginkannya pre-split. (Meskipun lebih umum menggunakan aturan catch-all, dan biarkan skrip itu sendiri memperluas segmen dari REQUEST_URI.)Lihat juga: Bagaimana cara mengubah segmen jalur URL saya menjadi pasangan nilai kunci string kueri?
Segmen opsional
prefix/opt?/.*
Variasi umum adalah memiliki awalan opsional di dalam aturan. Ini biasanya masuk akal jika Anda memiliki string statis atau placeholder yang lebih terbatas di sekitar:
Sekarang pola yang lebih kompleks di
(?:/([^/])+)?
sana hanya membungkus kelompok yang tidak menangkap(?:…)
, dan menjadikannya opsional)?
. Tempat penampung yang ada([^/]+)
akan menjadi pola substitusi$2
, tetapi kosong jika tidak ada/…/
jalan tengah .Tangkap sisanya
/prefix/123-capture/…/*/…whatever…
Seperti yang dikatakan sebelumnya, Anda tidak sering menginginkan pola penulisan ulang yang terlalu umum. Namun masuk akal untuk menggabungkan perbandingan statis dan spesifik dengan
.*
kadang - kadang.Ini memilih semua
/…/…/…
segmen jalur tambahan. Yang kemudian tentu saja memerlukan skrip penanganan untuk membaginya, dan variabl-ify diekstraksi parameter itu sendiri (yang adalah apa yang dilakukan kerangka kerja "MVC" ).Membuntuti file "ekstensi"
/old/path.HTML
URL tidak benar-benar memiliki ekstensi file. Itulah keseluruhan referensi ini (= URL adalah pelacak virtual, tidak harus berupa gambar sistem file langsung). Namun jika Anda memiliki pemetaan file 1: 1 sebelumnya, Anda dapat membuat aturan yang lebih sederhana:
Kegunaan umum lainnya adalah memetakan kembali
.html
jalur yang usang ke.php
penangan yang lebih baru , atau hanya dengan alias nama direktori hanya untuk file individu (aktual / nyata).Ping-Pong (pengalihan dan penulisan ulang serempak)
/ugly.html
← →/pretty
Jadi pada titik tertentu Anda menulis ulang halaman HTML Anda untuk hanya membawa tautan yang cantik, seperti yang diuraikan oleh tipuan . Sementara itu, Anda masih akan menerima permintaan untuk jalur lama , terkadang bahkan dari bookmark. Sebagai solusinya , Anda dapat melakukan ping-pong browser untuk menampilkan / membuat URL baru.
Trik umum ini melibatkan pengiriman 30x / Lokasi redirect setiap kali URL yang masuk mengikuti skema penamaan yang usang / jelek. Browser kemudian akan me - rerequest URL baru / cantik, yang kemudian ditulis ulang (hanya secara internal) ke lokasi asli atau baru.
Perhatikan bagaimana contoh ini hanya digunakan
[END]
alih-alih[L]
untuk alternatif yang aman. Untuk versi Apache 2.2 yang lebih lama, Anda dapat menggunakan solusi lain, selain juga memetakan ulang parameter string kueri misalnya: Redirect URL jelek ke cantik, remap kembali ke jalur jelek, tanpa loop tak terbatasSpasi ␣dalam pola
/this+that+
Ini tidak cantik di bilah alamat browser, tetapi Anda dapat menggunakan spasi di URL. Untuk menulis ulang pola, gunakan
\␣
spasi backslash-escape . Lain-lain-"
kutip seluruh pola atau substitusi:Klien membuat serial URL dengan
+
atau%20
untuk spasi. Namun dalam RewriteRules mereka ditafsirkan dengan karakter literal untuk semua segmen jalur relatif.Duplikat yang sering:
Catch-all untuk skrip dispatcher / front-controller pusat
Yang sering digunakan oleh kerangka kerja PHP atau script WebCMS / portal. Pemisahan jalur yang sebenarnya kemudian ditangani dalam PHP menggunakan
$_SERVER["REQUEST_URI"]
. Jadi secara konseptual itu kebalikan dari penanganan URL "per mod_rewrite". (Cukup gunakanFallBackResource
saja.)Hapus
www.
dari nama hostPerhatikan bahwa ini tidak menyalin string kueri, dll.
Lihat juga:
· Penulisan ulang URL untuk berbagai protokol di .htaccess
· Htaccess generik mengalihkan www ke non-www
· .htaccess - cara memaksa "www." secara generik?
Perhatikan bahwa kombo RewriteCond / RewriteRule dapat menjadi lebih kompleks, dengan kecocokan (
%1
dan$1
) bahkan berinteraksi di kedua arah:Panduan Apache - mod_rewrite intro , Hak Cipta 2015 The Apache Software Foundation, AL-2.0
Dialihkan ke
HTTPS://
Lihat juga: https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
"Menghapus" ekstensi PHP
Lihat juga: Menghapus ekstensi .php dengan mod_rewrite
Mengasingkan jalur .html lama ke skrip .php
Lihat: http://httpd.apache.org/docs/2.4/rewrite/remapping.html#backward-compatibility
Tulis ulang dari URL seperti "/ halaman" ke skrip seperti "/index.php/page"
Lihat mod_rewrite, php dan file .htaccess
Arahkan ulang subdomain ke folder
Lihat Bagaimana saya bisa membuat htaccess saya berfungsi (subdomain)?
lazim
.htaccess
perangkapSekarang ambil ini dengan sebutir garam. Tidak setiap saran dapat digeneralisasi untuk semua konteks. Ini hanya ringkasan sederhana dari batu sandungan yang terkenal dan beberapa yang tidak terlihat:
Aktifkan
mod_rewrite
dan.htaccess
Untuk benar-benar menggunakan RewriteRules dalam file konfigurasi per-direktori, Anda harus:
Periksa apakah server Anda telah
AllowOverride All
diaktifkan . Kalau tidak,.htaccess
arahan per-direktori Anda akan diabaikan, dan RewriteRules tidak akan berfungsi.Jelas telah
mod_rewrite
diaktifkan dihttpd.conf
bagian modul Anda .Tambahkan setiap daftar aturan dengan
RewriteEngine On
diam. Sementara mod_rewrite secara aktif aktif di dalam<VirtualHost>
dan<Directory>
bagian, file per-direktori.htaccess
memerlukannya secara individual dipanggil.Garis miring
^/
tidak akan cocokAnda seharusnya tidak memulai
.htaccess
pola RewriteRule Anda dengan^/
normal:Ini sering terlihat di tutorial lama. Dan itu dulu benar untuk versi Apache 1.x kuno. Saat ini jalur permintaan sepenuhnya direktori-relatif nyaman di
.htaccess
RewriteRules. Biarkan saja yang memimpin/
.· Perhatikan bahwa slash utama masih benar di
<VirtualHost>
beberapa bagian. Itulah sebabnya Anda sering melihatnya^/?
dipilih untuk paritas aturan.· Atau saat menggunakan
RewriteCond %{REQUEST_URI}
kamu akan tetap cocok untuk seorang pemimpin/
.· Lihat juga Webmaster.SE: Kapan garis miring (/) diperlukan dalam pola mod_rewrite?
<IfModule *>
pembungkus hilang!Anda mungkin pernah melihat ini dalam banyak contoh:
<VirtualHost>
bagian - jika itu dikombinasikan dengan opsi mundur lain, seperti ScriptAliasMatch. (Tapi tidak ada yang pernah melakukan itu)..htaccess
dengan banyak proyek sumber terbuka. Itu hanya dimaksudkan sebagai mundur, dan menjaga URL "jelek" berfungsi sebagai default.Namun Anda tidak ingin itu biasanya di Anda sendiri
.htaccess
file .500
kesalahan HTTP . Apa yang biasanya dicapai adalah menghias pengguna Anda dengan404
kesalahan HTTP . (Tidak terlalu banyak ramah pengguna jika Anda memikirkannya.)Jangan gunakan
RewriteBase
kecuali diperlukanBanyak contoh salin + tempel mengandung
RewriteBase /
arahan. Yang kebetulan merupakan default implisit. Jadi Anda tidak benar-benar membutuhkan ini. Ini merupakan solusi untuk skema penulisan ulang VirtualHost yang mewah, dan jalur DOCUMENT_ROOT yang disalahgunakan untuk beberapa host bersama.Masuk akal untuk digunakan dengan masing-masing aplikasi web di subdirektori yang lebih dalam. Ini dapat mempersingkat pola RewriteRule dalam kasus seperti itu. Secara umum yang terbaik adalah memilih penentu lintasan relatif dalam set aturan per-direktori.
Lihat juga Bagaimana cara kerja RewriteBase di .htaccess
Nonaktifkan
MultiViews
saat jalur virtual tumpang tindihPenulisan ulang URL terutama digunakan untuk mendukung jalur masuk virtual . Umumnya Anda hanya memiliki satu naskah operator (
index.php
) atau penangan beberapa individu (articles.php
,blog.php
,wiki.php
, ...). Yang terakhir mungkin berbenturan dengan jalur RewriteRule virtual serupa.Permintaan
/article/123
misalnya dapat dipetakan kearticle.php
dengan/123
PATH_INFO secara implisit. Anda harus menjaga aturan Anda denganRewriteCond
!-f
+ biasa!-d
, dan / atau menonaktifkan dukungan PATH_INFO, atau mungkin hanya menonaktifkanOptions -MultiViews
.Yang tidak berarti Anda harus selalu melakukannya . Negosiasi konten hanyalah otomatisme untuk sumber daya virtual.
Memesan itu penting
Lihat Segala sesuatu yang Anda ingin tahu tentang mod_rewrite jika Anda belum melakukannya. Menggabungkan beberapa RewriteRules sering menyebabkan interaksi. Ini bukan sesuatu untuk mencegah kebiasaan per
[L]
bendera, tetapi sebuah skema yang akan Anda terima setelah berpengalaman. Anda bisa kembali menulis ulang jalur virtual dari satu aturan ke aturan lain, hingga mencapai target handler yang sebenarnya.Tetap Anda sering ingin memiliki aturan yang paling spesifik (
/forum/…
pola string tetap , atau placeholder yang lebih ketat[^/.]+
) di aturan awal . Aturan slurp-all generik (.*
) lebih baik diserahkan kepada yang kemudian . (Pengecualian adalahRewriteCond -f/-d
pelindung sebagai blok utama.)Lembar gaya dan gambar berhenti berfungsi
Saat Anda memperkenalkan struktur direktori virtual,
/blog/article/123
ini memengaruhi referensi sumber daya relatif dalam HTML (seperti<img src=mouse.png>
). Yang bisa diselesaikan dengan:href="https://stackoverflow.com/old.html"
atausrc="/logo.png"
<base href="https://stackoverflow.com/index">
ke<head>
bagian HTML Anda . Ini secara implisit menolak referensi relatif ke apa yang sebelumnya.Anda juga dapat membuat RewriteRules lebih lanjut untuk rebind
.css
atau.png
path ke lokasi aslinya. Tapi itu tidak dibutuhkan, atau menimbulkan pengalihan tambahan dan menghambat caching.Lihat juga: CSS, JS dan gambar tidak ditampilkan dengan url cantik
RewriteConds cukup sembunyikan satu RewriteRule
Salah tafsir yang umum adalah bahwa RewriteCond memblokir beberapa RewriteRules (karena semuanya diatur secara visual bersama):
Yang tidak sesuai standar. Anda dapat rantai mereka menggunakan
[S=2]
bendera. Jika tidak, Anda harus mengulanginya. Meskipun terkadang Anda dapat membuat aturan utama "terbalik" untuk [AKHIR] proses penulisan ulang lebih awal.QUERY_STRING dikecualikan dari RewriteRules
Anda tidak dapat mencocokkan
RewriteRule index.php\?x=y
, karena mod_rewrite membandingkan hanya terhadap jalur relatif per default. Namun Anda dapat mencocokkannya secara terpisah melalui:Lihat juga Bagaimana saya bisa mencocokkan variabel string kueri dengan mod_rewrite?
.htaccess
vs.<VirtualHost>
Jika Anda menggunakan RewriteRules dalam file konfigurasi per-direktori, maka khawatir tentang kinerja regex tidak ada gunanya. Apache mempertahankan pola PCRE yang dikompilasi lebih lama dari proses PHP dengan kerangka kerja routing yang umum. Untuk situs dengan lalu lintas tinggi, Anda harus mempertimbangkan untuk memindahkan aturan ke konfigurasi server vhost, begitu mereka telah diuji pertempuran.
Dalam hal ini, lebih suka
^/?
awalan pemisah direktori yang di -pilih . Ini memungkinkan untuk memindahkan RewriteRules secara bebas antara PerDir dan file konfigurasi server.Kapan pun sesuatu tidak bekerja
Jangan khawatir.
Bandingkan
access.log
danerror.log
Seringkali Anda dapat mengetahui bagaimana Aturan Rewrite berlaku tidak adil hanya dengan melihat Anda
error.log
danaccess.log
. Korelasikan waktu akses untuk melihat jalur permintaan mana yang awalnya masuk, dan jalur / file mana yang tidak dapat diselesaikan oleh Apache (kesalahan 404/500).Ini tidak memberi tahu Anda siapa RewriteRule yang menjadi biang keladinya. Tapi jalan terakhir yang tidak dapat diakses seperti
/docroot/21-.itle?index.php
mungkin memberikan tempat untuk memeriksa lebih lanjut. Atau nonaktifkan aturan hingga Anda mendapatkan beberapa jalur yang dapat diprediksi.Aktifkan RewriteLog
Lihat Apache RewriteLog docs. Untuk debugging Anda dapat mengaktifkannya di bagian vhost:
Itu menghasilkan ringkasan terperinci tentang bagaimana jalur permintaan yang masuk dimodifikasi oleh setiap aturan:
Yang membantu untuk mempersempit aturan terlalu umum dan regex kecelakaan.
Lihat juga:
· .htaccess tidak berfungsi (mod_rewrite)
· Kiat untuk debugging .htaccess aturan penulisan ulang
Sebelum mengajukan pertanyaan Anda sendiri
Seperti yang Anda ketahui, Stack Overflow sangat cocok untuk mengajukan pertanyaan pada mod_rewrite. Jadikan sesuai topik dengan memasukkan penelitian dan upaya sebelumnya (hindari jawaban yang berlebihan), tunjukkan dasarregex pemahaman, dan:
$_SERVER
lingkungan PHP jika itu tentang ketidakcocokan parameter.access.log
danerror.log
untuk memverifikasi apa aturan yang ada diselesaikan untuk. Lebih baik lagi,rewrite.log
ringkasan.Ini menjaring jawaban yang lebih cepat dan lebih tepat, dan membuatnya lebih bermanfaat bagi orang lain.
Beri komentar
.htaccess
Jika Anda menyalin contoh dari suatu tempat, berhati-hatilah untuk memasukkan a
# comment and origin link
. Sementara itu hanya perilaku buruk untuk menghilangkan atribusi, itu sering benar-benar menyakitkan pemeliharaan nanti. Dokumentasikan kode atau sumber tutorial apa pun. Khususnya saat tidak berversi Anda harus lebih tertarik untuk tidak memperlakukan mereka seperti kotak hitam ajaib.Ini bukan "SEO" -URLs
Penafian: Hanya kencing kesayangan. Anda sering mendengar skema penulisan ulang URL yang cantik yang disebut tautan "SEO" atau semacamnya. Meskipun ini berguna untuk contoh-contoh googling, ini adalah istilah yang salah tanggal.
Tidak ada mesin pencari modern yang benar-benar terganggu oleh
.html
dan.php
di segmen jalur, atau?id=123
string kueri dalam hal ini. Mesin pencari lama, seperti AltaVista, melakukannya menghindari merayapi situs web dengan jalur akses yang berpotensi ambigius. Perayap modern bahkan sering mendambakan sumber daya web yang dalam.Apa yang "cantik" URL harus secara konseptual digunakan untuk membuat situs web ramah pengguna .
/common/tree/nesting
.Namun jangan mengorbankan persyaratan unik untuk konformisme.
Alat
Ada berbagai alat online untuk menghasilkan RewriteRules untuk sebagian besar URL GET-parameterish:
Sebagian besar hanya menampilkan
[^/]+
penampung generik, tetapi kemungkinan cukup untuk situs sepele.sumber
Alternatif untuk mod_rewrite
Banyak skema URL virtual dasar dapat dicapai tanpa menggunakan RewriteRules. Apache memungkinkan skrip PHP dipanggil tanpa
.php
ekstensi, dan denganPATH_INFO
argumen virtual .Gunakan PATH_INFO , Luke
Saat
AcceptPathInfo On
ini sering diaktifkan secara default. Yang pada dasarnya memungkinkan.php
dan URL sumber daya lainnya untuk membawa argumen virtual:Sekarang ini
/virtual/path
muncul di PHP sebagai$_SERVER["PATH_INFO"]
tempat Anda dapat menangani argumen tambahan apa pun yang Anda suka.Hal ini tidak nyaman seperti memiliki Apache segmen jalan input terpisah ke dalam
$1
,$2
,$3
dan melewati mereka sebagai berbeda$_GET
variabel untuk PHP. Ini hanya meniru "URL cantik" dengan sedikit upaya konfigurasi.Aktifkan MultiViews untuk menyembunyikan
.php
ekstensiOpsi paling sederhana untuk juga menghindari
.php
"ekstensi file" di URL adalah memungkinkan:Ini membuat Apache memilih
article.php
permintaan HTTP pada/article
karena nama dasarnya yang cocok. Dan ini bekerja dengan baik bersama dengan fitur PATH_INFO yang disebutkan di atas. Jadi Anda bisa menggunakan URL sepertihttp://example.com/article/virtual/title
. Yang masuk akal jika Anda memiliki aplikasi web tradisional dengan beberapa poin / skrip permohonan PHP.Perhatikan bahwa MultiViews memiliki tujuan yang berbeda / lebih luas. Ini menimbulkan penalti kinerja yang sangat kecil , karena Apache selalu mencari file lain dengan nama dasar yang cocok. Ini benar-benar dimaksudkan untuk Content-Negosiasi , sehingga browser menerima alternatif terbaik di antara sumber daya yang tersedia (seperti
article.en.php
,article.fr.php
,article.jp.mp4
).SetType atau SetHandler untuk
.php
skrip tanpa ekstensiPendekatan yang lebih terarah untuk menghindari membawa
.php
sufiks dalam URL adalah mengonfigurasi PHP handler untuk skema file lainnya. Opsi paling sederhana adalah mengganti tipe MIME / handler default melalui.htaccess
:Dengan cara ini Anda bisa mengganti nama
article.php
skrip Anda menjadi adilarticle
(tanpa ekstensi), tetapi masih memprosesnya sebagai skrip PHP.Sekarang ini dapat memiliki beberapa implikasi keamanan dan kinerja, karena semua file tanpa ekstensi akan disalurkan melalui PHP sekarang. Karenanya, Anda dapat mengatur perilaku ini sebagai alternatif untuk file individual saja:
Ini agak tergantung pada pengaturan server Anda dan PHP SAPI yang digunakan. Alternatif umum termasuk
ForceType application/x-httpd-php
atauAddHandler php5-script
.Skema penulisan ulang Apache lainnya
Di antara banyak pilihannya, Apache menyediakan
mod_alias
fitur - yang kadang-kadang berfungsi sama baiknya denganmod_rewrite
RewriteRules. Perhatikan bahwa sebagian besar dari mereka harus diatur dalam suatu<VirtualHost>
bagian, tidak dalam.htaccess
file konfigurasi per-direktori .ScriptAliasMatch
terutama untuk skrip CGI, tetapi juga harus berfungsi untuk PHP. Ini memungkinkan regexps sama seperti apa punRewriteRule
. Bahkan itu mungkin opsi paling kuat untuk mengkonfigurasi pengontrol depan catch-all.Dan polos
Alias
membantu dengan beberapa skema penulisan ulang sederhana juga.Bahkan
ErrorDocument
arahan sederhana dapat digunakan untuk membiarkan skrip PHP menangani jalur virtual. Perhatikan bahwa ini adalah solusi kludgy, tetapi melarang permintaan GET, dan membanjiri error.log menurut definisi.Lihat http://httpd.apache.org/docs/2.2/urlmapping.html untuk tips lebih lanjut.
sumber