Redirect, Ubah URL atau Redirect HTTP ke HTTPS di Apache - Segala Sesuatu yang Pernah Anda Ingin Ketahui Tentang Aturan Mod_Rewrite tetapi Takut untuk Meminta

264

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.

Kyle Brandt
sumber
9
Gagasan di balik pertanyaan ini adalah untuk memberikan jalan yang dekat untuk semua pertanyaan mod_rewrite tak berujung yang membuat pengguna reguler kami lebih gila. Ini sangat mirip dengan apa yang dilakukan dengan subnetting di serverfault.com/questions/49765/how-does-subnetting-work .
Kyle Brandt
1
Juga, saya tidak benar-benar ingin terlalu banyak upvotes pada pertanyaan ini , mereka harus pergi ke jawabannya. Saya tidak ingin CW ini karena saya ingin memastikan poster mendapatkan kredit penuh untuk apa yang saya harapkan adalah jawaban mod_rewrite untuk mengakhiri semua pertanyaan mod_rewrite .
Kyle Brandt
4
Maaf, saya membatalkan pertanyaan. ;-) Saya benar-benar berpikir itu perlu muncul di (atau dekat) bagian atas mod-rewritepencarian tag / filter.
Steven Monday
Seseorang yang lain (tm) harus menangani kasus penggunaan umum. Saya tidak tahu mereka cukup baik untuk melakukannya keadilan.
sysadmin1138
Mungkin pertanyaan ini harus dikaitkan dengan mod-rewrite tag wiki untuk membuat path lebih pendek.
beldaz

Jawaban:

224

pesanan sintaks mod_rewrite

mod_rewrite memiliki beberapa aturan pemesanan khusus yang memengaruhi pemrosesan. Sebelum apa pun dilakukan, RewriteEngine Onarahan perlu diberikan karena ini mengaktifkan pemrosesan mod_rewrite. Ini harus ada sebelum arahan penulisan ulang lainnya.

RewriteCondsebelumnya RewriteRulemembuat bahwa SATU aturan tunduk pada persyaratan. Setiap RewriteRules berikut akan diproses seolah-olah mereka tidak tunduk pada persyaratan.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Tetapi mungkin harus dilakukan dengan beberapa sintaks pengganti yang lebih rumit.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteRule yang lebih kompleks berisi persyaratan untuk diproses. Tanda kurung terakhir, (html|jpg)memberi tahu RewriteRule untuk mencocokkan salah satu htmlatau jpg, 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):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Untuk melayani halaman yang dirujuk oleh ServerFault dengan browser Chrome (DAN implisit):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBasejuga dipesan khusus karena menentukan cara RewriteRulearahan 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:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

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, RewriteRuleanggap itu string-mulai setelah "/ blog" di URL. Berikut adalah hal yang sama ditulis dua cara berbeda. Satu dengan RewriteBase, yang lain tanpa:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Seperti yang Anda lihat, RewriteBasememungkinkan 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.

RewriteRule ^/blog/(.*)$    /newblog/$1

The .*konstruk cocok dengan karakter tunggal ( .) nol atau lebih kali ( *). Melampirkannya di dalam tanda kurung menyuruhnya memberikan string yang cocok dengan variabel $ 1.

RewriteRule ^/blog/.*/(.*)$  /newblog/$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).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

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.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

Dalam hal ini, kami menggunakan $ 1 dalam string yang ditulis ulang.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

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.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

Ini melakukan hal yang sama dengan aturan sebelumnya, tetapi bagian {2} mengatakannya untuk mencocokkan karakter sebelumnya (ekspresi kurung dalam kasus ini) dua kali.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

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.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Ini menjebak nama file dengan tanda hubung di dalamnya. Namun, seperti -karakter khusus dalam ekspresi braket, itu harus menjadi karakter pertama dalam ekspresi.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

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 .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

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. Memungkinkanjpguntuk 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 AddTypearahan.

Anda tahu bagaimana saya mengatakan itu RewriteCondberlaku untuk satu dan hanya satu aturan? Nah, Anda bisa menyiasatinya dengan merantai.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

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.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Ini dapat dibuat lebih sederhana melalui flag:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Juga, beberapa flag juga berlaku untuk RewriteCond. Khususnya, NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Akan cocok dengan "ServerFault.com"

sysadmin1138
sumber
9
Sudah selesai dilakukan dengan baik. [filler]
EEAA
3
mod_rewritePrimer sangat bagus dan regex. +1.
Steven Monday
3
Kadang-kadang berguna untuk mengetahui bahwa RewriteCondsebenarnya diproses setelah yang RewriteRulecocok. 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 ..."
Dennis Williamson
2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1tidak 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.
adapttr
1
@ sysadmin1138, saya pikir jawaban ini baik tetapi bisa lebih baik jika Anda menguraikan lebih lanjut pada bendera E, N, NS, P, PT, dan S dengan contoh-contoh karena bendera-bendera itu tidak jelas cara kerjanya dll.
Pacerier
39

Apa format dan struktur mendasar dari aturan mod_rewrite?

Saya akan tunduk pada jawaban yang sangat baik dari sysadmin1138 tentang poin-poin ini.

Apa bentuk / rasa dari ekspresi reguler yang perlu saya pahami?

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.

Apa kesalahan / jebakan paling umum saat menulis aturan penulisan ulang?

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:

  • 500 - Galat Server Internal - Hapus kontrol carriage Windows di file konfigurasi jika ada, pastikan mod_rewrite diaktifkan (bungkus arahan dalam IfModulekondisi kondisional untuk menghindari skenario ini), periksa sintaks direktif, komentar arahan sampai komentar masalah
  • Redirect loop - Manfaatkan RewriteLog dan RewriteLogLevel, komentar keluar arahan sampai masalah teridentifikasi

Apa metode yang baik untuk menguji dan memverifikasi aturan mod_rewrite?

Pertama, lihat isi variabel lingkungan yang Anda rencanakan cocokkan - jika Anda memasang PHP, ini sesederhana menambahkan blok berikut ke aplikasi Anda:

<?php
  var_dump($_SERVER);
?>

... 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 RewriteLogarahan mod_rewrite untuk mencatat aktivitas ke file dan mengaturRewriteLogLevel 3

Adakah implikasi SEO atau kinerja dari aturan mod_rewrite yang harus saya ketahui?

AllowOverride allberdampak pada kinerja server karena Apache harus memeriksa .htaccessfile dan arahan parsing dengan setiap permintaan - jika memungkinkan, simpan semua arahan dalam konfigurasi VirtualHost untuk situs Anda atau aktifkan .htaccesspenggantian 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.

Apakah ada situasi umum di mana mod_rewrite mungkin tampak seperti alat yang tepat untuk pekerjaan itu tetapi tidak?

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.

Apa saja contoh umum?

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).

danlefree
sumber
Terima kasih atas tautan AskApache. Itu yang saya cari!
sica07
Badut AskApache secara resmi tidak didukung oleh ASF. Banyak dari apa yang dia katakan bisa diperdebatkan atau salah.
adapttr
@adaptr Silakan bagikan sumber daya superior yang tampaknya Anda ketahui.
danlefree
"Situasi umum di mana mod_rewrite mungkin tampak seperti alat yang tepat untuk pekerjaan itu tetapi bukan?" - pengalihan sederhana , di mana mod_rewrite belum digunakan. Gunakan mod_alias Redirectatau RedirectMatchsebagai gantinya. Lihat juga dokumen Apache: Kapan tidak menggunakan mod_rewrite
MrWhite
21

Seperti 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_rewritesebenarnya bekerja dan berinteraksi dengan anggota Apache lainnya. inti, jadi selama beberapa bulan terakhir saya telah menginstruksikan kasus uji dengan strace+ menelusuri kode sumber untuk menangani semua ini.

Berikut adalah beberapa komentar kunci yang perlu dipertimbangkan pengembang menulis ulang:

  • Beberapa aspek menulis ulang yang umum untuk konfigurasi server, virtual host, direktori, htaccess pengolahan namun
  • Beberapa pemrosesan sangat berbeda untuk konfigurasi root (konfigurasi server, virtual host dan direktori) dibandingkan dengan .htaccesspemrosesan PerDir ( ).
  • Lebih buruk lagi karena pemrosesan PerDir dapat hampir tanpa dipicu memicu perputaran INTERNAL REDIRECT, elemen konfigurasi root harus ditulis sadar bahwa pemrosesan PerDir tersebut dapat memicu ini.

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 .htaccessfile 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) .

    • Pengguna tersebut harus menggunakan .htaccesspemrosesan / Perdir karena tidak ada alternatif yang tersedia.
    • Lebih buruk lagi, tingkat keterampilan pengguna tersebut (sejauh menggunakan logika tangga-regexp digerakkan mod_rewrite) umumnya jauh lebih sedikit daripada admin berpengalaman.
    • Apache dan penyedia hosting tidak menawarkan dukungan debugging / diagnostik. Satu-satunya informasi diagnostik adalah pengalihan sukses, pengalihan ke URI yang salah. atau kode status 404/500. Ini membuat mereka bingung dan tidak berdaya.
    • Apache sangat lemah menjelaskan bagaimana penulisan ulang bekerja untuk use case ini. Misalnya tidak memberikan penjelasan yang jelas tentang .htaccessfile 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 .htaccesspengguna, saya merasa bahwa kami perlu mengembangkan dan menawarkan:

  • Deskripsi yang koheren tentang bagaimana sebenarnya sistem penulisan ulang bekerja dalam pemrosesan PerDir
  • Seperangkat pedoman / praktik terbaik tentang cara menulis .htaccessaturan penulisan ulang
  • Jenis parser penulisan ulang skrip berbasis web sederhana yang mirip dengan parser html W3C, tetapi dengan mana pengguna dapat memasukkan URI pengujian atau vektor uji yang sama dan mendapatkan log langsung dari aliran logika penulisan ulang /
  • Petunjuk tentang cara mendapatkan diagnostik bawaan dari aturan Anda (mis

    • Gunakan [E=VAR:EXPR]mengeksploitasi fakta yang EXPRakan 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:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      
TerryE
sumber
Ini didokumentasikan dengan baik. Mengapa menurut Anda dokumentasi tidak menjelaskan hal ini?
adapttr
2
Yang harus Anda lakukan adalah berlangganan .htaccesstopik 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 .htaccessfile. 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. :-(
TerryE
Saya sangat setuju. "Kita perlu membagi komunitas pengguna yang menulis ulang menjadi dua kategori dan memperlakukannya sebagai sepenuhnya terpisah." Beberapa pengguna menggunakan shared hosting dan perlu untuk diandalkan .htaccess, yang sangat rapuh, rumit, dan membingungkan, bahkan untuk para ahli. Saya MASIH mengalami masalah.
Ryan
15

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:

RewriteMap MapName MapType:MapSource

Sebagai contoh:

RewriteMap examplemap txt:/path/to/file/map.txt

Anda kemudian dapat menggunakan mapname untuk konstruksi seperti ini:

${examplemap:key}

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 ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

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 ...

Krist van Besien
sumber
Kalimat terakhir tidak sepenuhnya benar. Mesin mod_rewriteregexp mendukung kelompok yang tidak menangkap seperti (?:location|place)dan ini hanya akan memiliki satu tangkapan dalam contoh.
TerryE
12

Apa kesalahan / jebakan paling umum saat menulis aturan penulisan ulang?

Jebakan yang sangat mudah adalah ketika Anda menulis ulang URL yang mengubah jalur yang terlihat, misalnya dari /base/1234/index.htmlmenjadi /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 .

beldaz
sumber
1
Terima kasih untuk tautannya. Khususnya ketika bekerja dengan anggota tim lain yang tidak terbiasa dengan penulisan ulang, saya menemukan menambahkan <base>tag yang paling mudah diikuti dan masih memungkinkan jalur relatif.
kontur