Tips untuk men-debug aturan penulisan ulang .htaccess

Feb 06 2012

Banyak poster mengalami masalah dalam men-debug pernyataan RewriteRule dan RewriteCond di dalam .htaccessfile mereka . Sebagian besar menggunakan layanan hosting bersama dan oleh karena itu tidak memiliki akses ke konfigurasi server root. Mereka tidak dapat menghindari penggunaan .htaccessfile untuk menulis ulang dan tidak dapat mengaktifkan RewriteLogLevel "seperti yang disarankan oleh banyak responden. Juga ada banyak .htaccesskendala dan kendala khusus yang tidak tercakup dengan baik. Menyiapkan tumpukan LAMP pengujian lokal melibatkan terlalu banyak kurva pembelajaran bagi sebagian besar orang .

Jadi Q saya di sini adalah bagaimana kami merekomendasikan agar mereka men - debug aturan mereka sendiri . Saya memberikan beberapa saran di bawah ini. Saran lain akan dihargai.

  1. Pahami bahwa mesin mod_rewrite melakukan siklus melalui .htaccessfile . Mesin menjalankan loop ini:

    do
      execute server and vhost rewrites (in the Apache Virtual Host Config)
      find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled
      if found(.htaccess)
         execute .htaccess rewrites (in the user's directory)
    while rewrite occurred
    

    Jadi aturan Anda akan dieksekusi berulang kali dan jika Anda mengubah jalur URI maka itu mungkin berakhir dengan mengeksekusi .htaccessfile lain jika ada. Jadi, pastikan Anda menghentikan loop ini, jika perlu dengan menambahkan ekstra RewriteConduntuk menghentikan pengaktifan aturan. Hapus juga semua .htaccesskumpulan aturan penulisan ulang level yang lebih rendah kecuali secara eksplisit bermaksud menggunakan kumpulan aturan multi-level.

  2. Pastikan sintaks dari setiap Ekspresi Reguler sudah benar dengan menguji serangkaian pola pengujian untuk memastikannya merupakan sintaks yang valid dan melakukan apa yang Anda inginkan dengan berbagai URI pengujian. Lihat jawaban di bawah untuk lebih jelasnya.

  3. Buat aturan Anda secara bertahap dalam direktori pengujian. Anda dapat menggunakan fitur "jalankan .htaccessfile terdalam di jalur" untuk menyiapkan direktori pengujian terpisah (pohon) dan men-debug kumpulan aturan di sini tanpa mengacaukan aturan utama dan menghentikan kerja situs Anda. Anda harus menambahkannya satu per satu karena ini adalah satu-satunya cara untuk melokalkan kegagalan ke aturan individu.

  4. Gunakan rintisan skrip tiruan untuk membuang variabel server dan lingkungan . (Lihat Cantuman 2 ) Jika aplikasi Anda menggunakan, katakanlah, blog/index.phpAnda dapat menyalin ini ke test/blog/index.phpdan menggunakannya untuk menguji aturan blog Anda di testsubdirektori. Anda juga dapat menggunakan variabel lingkungan untuk memastikan bahwa mesin penulisan ulang dalam menafsirkan string substitusi dengan benar, misalnya

    RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]
    

    dan cari variabel REDIRECT_ * ini di dump phpinfo. BTW, saya menggunakan yang ini dan menemukan di situs saya bahwa saya harus menggunakan %{ENV:DOCUMENT_ROOT_REAL}sebagai gantinya. Dalam kasus redirector perulangan variabel REDIRECT_REDIRECT_ * daftar lintasan sebelumnya. Dll ..

  5. Pastikan Anda tidak digigit oleh browser Anda yang menyimpan pengalihan 301 yang salah . Lihat jawabannya di bawah . Terima kasih saya kepada Ulrich Palha untuk ini.

  6. Mesin penulisan ulang tampaknya sensitif terhadap aturan bertingkat dalam .htaccesskonteks, (di situlah RewriteRulehasil dalam substitusi dan ini jatuh ke aturan lebih lanjut), karena saya menemukan bug dengan sub-permintaan internal (1) , dan pemrosesan PATH_INFO yang salah yang sering kali dapat terjadi. dicegah dengan menggunakan flag [NS], [L] dan [PT].

Ada komentar atau saran lagi?

Daftar 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);

Jawaban

137 UlrichPalha Feb 09 2012 at 08:50

Berikut adalah beberapa tip tambahan tentang aturan pengujian yang dapat memudahkan debugging untuk pengguna di shared hosting

1. Gunakan agen pengguna palsu

Saat menguji aturan baru, tambahkan kondisi untuk hanya menjalankannya dengan fakeagen pengguna yang akan Anda gunakan untuk permintaan Anda. Dengan cara ini, ini tidak akan memengaruhi orang lain di situs Anda.

misalnya

#protect with a fake user agent
RewriteCond %{HTTP_USER_AGENT}  ^my-fake-user-agent$ #Here is the actual rule I am testing RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC] 
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [L,R=302] 

Jika Anda menggunakan Firefox, Anda dapat menggunakan User Agent Switcher untuk membuat string dan pengujian agen pengguna palsu.

2. Jangan gunakan 301 sampai Anda selesai melakukan pengujian

Saya telah melihat begitu banyak postingan di mana orang-orang masih menguji aturan mereka dan mereka menggunakan 301. JANGAN .

Jika Anda tidak menggunakan saran 1 di situs Anda, tidak hanya Anda, tetapi siapa pun yang mengunjungi situs Anda pada saat itu akan terpengaruh oleh 301.

Ingatlah bahwa mereka permanen, dan secara agresif di-cache oleh browser Anda. Gunakan 302 sebagai gantinya sampai Anda yakin, lalu ubah ke 301.

3. Ingatlah bahwa 301 di-cache secara agresif di browser Anda

Jika aturan Anda tidak berfungsi dan tampaknya benar bagi Anda, dan Anda tidak menggunakan saran 1 dan 2, maka uji ulang setelah mengosongkan cache browser atau saat dalam penelusuran pribadi.

4. Gunakan alat HTTP Capture

Gunakan alat penangkap HTTP seperti Fiddler untuk melihat lalu lintas HTTP yang sebenarnya antara browser Anda dan server.

Sementara orang lain mungkin mengatakan itu milik Anda site does not look right, Anda malah bisa melihat dan melaporkannya all of the images, css and js are returning 404 errors, dengan cepat mempersempit masalahnya.

Sementara orang lain akan melaporkan bahwa Anda started at URL A and ended at URL C, Anda akan dapat melihat bahwa mereka memulai pada URL A, were 302 redirected to URL B and 301 redirected to URL C. Meskipun URL C adalah tujuan akhir, Anda akan tahu bahwa ini buruk untuk SEO dan perlu diperbaiki.

Anda akan dapat melihat header cache yang ditetapkan di sisi server, memutar ulang permintaan, mengubah header permintaan untuk menguji ....


87 JCastell Feb 06 2014 at 21:44

Pengujian penulisan ulang .htaccess online

Saya menemukan ini Googling untuk regex bantuan, itu menyelamatkan saya banyak waktu dari keharusan untuk meng-upload baru .htaccessfile setiap kali saya melakukan sedikit modifikasi.

dari situs:

htaccess tester

Untuk menguji aturan penulisan ulang htaccess Anda, cukup isi url yang Anda terapkan aturannya, tempatkan konten htaccess Anda pada area input yang lebih besar dan tekan tombol "Periksa Sekarang".

13 KristvanBesien Jun 21 2013 at 14:03

Jangan lupa bahwa dalam file .htaccess ini adalah URL relatif yang cocok.

Dalam file .htaccess, RewriteRule berikut tidak akan pernah cocok:

RewriteRule ^/(.*)     /something/$s
8 Ruben Feb 04 2013 at 19:26

Satu dari beberapa jam yang saya buang:

Jika Anda telah menerapkan semua tip ini dan hanya melakukan 500 kesalahan karena Anda tidak memiliki akses ke log kesalahan server, mungkin masalahnya bukan pada .htaccess tetapi pada file yang dialihkan.

Setelah saya memperbaiki masalah .htaccess saya, saya menghabiskan dua jam lagi untuk mencoba memperbaikinya lagi, meskipun saya lupa tentang beberapa izin.

8 TerryE Feb 13 2012 at 21:11

Pastikan sintaks setiap Ekspresi Reguler sudah benar

dengan menguji serangkaian pola pengujian untuk memastikannya merupakan sintaks yang valid dan melakukan apa yang Anda inginkan dengan berbagai URI pengujian.

Lihat regexpCheck.php di bawah ini untuk skrip sederhana yang dapat Anda tambahkan ke direktori private / test di situs Anda untuk membantu Anda melakukan ini. Saya telah menyimpan singkat ini daripada cantik. Cukup tempelkan ini ke dalam file regexpCheck.phpdi direktori pengujian untuk digunakan di situs web Anda. Ini akan membantu Anda membangun regexp dan mengujinya dengan daftar kasus uji saat Anda melakukannya. Saya menggunakan mesin PCRE PHP di sini, tetapi setelah melihat sumber Apache, ini pada dasarnya identik dengan yang digunakan di Apache. Ada banyak HowTos dan tutorial yang menyediakan templat dan dapat membantu Anda membangun keterampilan regexp Anda.

Kode 1 - regexpCheck.php

<html><head><title>Regexp checker</title></head><body>
<?php 
    $a_pattern= isset($_POST['pattern']) ? $_POST['pattern'] : ""; $a_ntests = isset($_POST['ntests']) ? $_POST['ntests'] : 1;
    $a_test = isset($_POST['test']) ? $_POST['test'] : array(); $res = array(); $maxM=-1; foreach($a_test as $t ){ $rtn = @preg_match('#'.$a_pattern.'#',$t,$m); if($rtn == 1){
            $maxM=max($maxM,count($m)); $res[]=array_merge( array('matched'),  $m ); } else { $res[]=array(($rtn === FALSE ? 'invalid' : 'non-matched')); } } ?> <p>&nbsp; </p> <form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
    <label for="pl">Regexp Pattern: </label>
    <input id="p" name="pattern" size="50" value="<?php echo htmlentities($a_pattern,ENT_QUOTES,"UTF-8");;?>" /> <label for="n">&nbsp; &nbsp; Number of test vectors: </label> <input id="n" name="ntests" size="3" value="<?php echo $a_ntests;?>"/>
    <input type="submit" name="go" value="OK"/><hr/><p>&nbsp;</p>
    <table><thead><tr><td><b>Test Vector</b></td><td>&nbsp; &nbsp; <b>Result</b></td>
<?php 
    for ( $i=0; $i<$maxM; $i++ ) echo "<td>&nbsp; &nbsp; <b>\$$i</b></td>"; echo "</tr><tbody>\n"; for( $i=0; $i<$a_ntests; $i++ ){ echo '<tr><td>&nbsp;<input name="test[]" value="', htmlentities($a_test[$i], ENT_QUOTES,"UTF-8"),'" /></td>'; foreach ($res[$i] as $v) { echo '<td>&nbsp; &nbsp; ',htmlentities($v, ENT_QUOTES,"UTF-8"),'&nbsp; &nbsp; </td>';}
        echo "</tr>\n";
    }
?> </table></form></body></html>
7 Simon Jan 29 2013 at 19:50

Pastikan Anda menggunakan tanda persen di depan variabel, bukan tanda dolar.

Ini %{HTTP_HOST}, tidak ${HTTP_HOST} . Tidak akan ada apa pun di error_log, tidak akan ada Kesalahan Server Internal, regexp Anda masih benar, aturan tidak akan cocok. Ini benar-benar mengerikan jika Anda sering bekerja dengan template django / genshi dan memiliki ${}substitusi variabel dalam memori otot.

7 Flimm Jul 22 2015 at 20:31

Tetapkan variabel lingkungan dan gunakan header untuk menerimanya:

Anda dapat membuat variabel lingkungan baru dengan baris RewriteRule, seperti yang disebutkan oleh OP:

RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]

Tetapi jika Anda tidak bisa mendapatkan skrip sisi server untuk bekerja, bagaimana Anda bisa membaca variabel lingkungan ini? Salah satu solusinya adalah mengatur tajuk:

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

Nilai menerima penentu format , termasuk %{NAME}epenentu untuk variabel lingkungan (jangan lupa huruf kecil e). Terkadang, Anda perlu menambahkan REDIRECT_awalan, tetapi saya belum berhasil saat awalan ditambahkan dan saat tidak.

5 flm Mar 14 2017 at 22:42

Jika Anda membuat pengalihan, uji dengan curl untuk menghindari masalah cache browser. Gunakan -I untuk mengambil header http saja. Gunakan -L untuk mengikuti semua pengalihan.

3 Lambart Jul 31 2012 at 02:54

Saya menemukan pertanyaan ini saat mencoba men-debug masalah mod_rewrite saya, dan pertanyaan itu pasti memiliki beberapa saran yang berguna. Tetapi pada akhirnya yang paling penting adalah memastikan Anda memiliki sintaks regex yang benar. Karena masalah dengan sintaks RE saya sendiri, menginstal skrip regexpCheck.php bukanlah pilihan yang tepat.

Tetapi karena Apache menggunakan Perl-Compatible Regular Expressions (PCRE), alat apa pun yang membantu menulis PCRE akan membantu. Saya telah menggunakan alat RegexPlanet dengan Java dan Javascript REs di masa lalu, dan senang mengetahui bahwa mereka juga mendukung Perl.

Cukup ketikkan ekspresi reguler Anda dan satu atau beberapa contoh URL, dan ini akan memberi tahu Anda jika ekspresi reguler cocok ("1" di kolom "~ =") dan jika berlaku, semua grup yang cocok (angka dalam "pemisahan" kolom akan sesuai dengan angka yang diharapkan Apache, misalnya $1, $2 dll.) Untuk setiap URL. Mereka mengklaim dukungan PCRE adalah "dalam versi beta", tetapi hanya itulah yang saya butuhkan untuk menyelesaikan masalah sintaks saya.

http://www.regexplanet.com/advanced/perl/index.html

Saya hanya akan menambahkan komentar ke jawaban yang ada tetapi reputasi saya belum pada level itu. Semoga ini bisa membantu seseorang.

3 Doin Mar 15 2013 at 05:16

Mengenai 4., Anda masih perlu memastikan bahwa "stub skrip tiruan" Anda sebenarnya adalah URL target setelah semua penulisan ulang selesai, atau Anda tidak akan melihat apa pun!

Trik serupa / terkait (lihat pertanyaan ini ) adalah memasukkan aturan sementara seperti:

RewriteRule (.*) /show.php?url=$1 [END]

Di mana show.phpada beberapa skrip yang sangat sederhana yang hanya menampilkan $_GETparameternya (Anda juga dapat menampilkan variabel lingkungan, jika Anda mau).

Ini akan menghentikan penulisan ulang pada saat Anda memasukkannya ke dalam kumpulan aturan, seperti breakpoint di debugger.

Jika Anda menggunakan Apache <2.3.9, Anda harus menggunakan [L]daripada [END], dan Anda mungkin perlu menambahkan:

RewriteRule ^show.php$ - [L]

Di bagian paling atas kumpulan aturan Anda, jika URL /show.phpitu sendiri sedang ditulis ulang.

3 AbhishekGurjar Mar 27 2017 at 16:57

Beberapa kesalahan yang saya amati terjadi saat menulis .htaccess

Penggunaan ^(.*)$berulang dalam beberapa aturan, penggunaan ^(.*)$menyebabkan aturan lain menjadi impoten dalam banyak kasus, karena cocok dengan semua url dalam satu klik.

Jadi, jika kita menggunakan aturan untuk url ini, sapmle/urlitu juga akan mengkonsumsi url ini sapmle/url/string.


[L] bendera harus digunakan untuk memastikan aturan kami telah selesai diproses.


Harus tahu tentang:

Selisih dalam% n dan $ n

%ndicocokkan selama %{RewriteCond}sebagian dan $ncocok %{RewriteRule}sebagian.

Bekerja dari RewriteBase

Direktif RewriteBase menentukan prefiks URL yang akan digunakan untuk direktif RewriteRule per direktori (htaccess) yang menggantikan jalur relatif.

Direktif ini diperlukan saat Anda menggunakan jalur relatif dalam substitusi dalam konteks per direktori (htaccess) kecuali jika 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). Di Apache HTTP Server 2.4.16 dan yang lebih baru, arahan ini dapat dihilangkan ketika permintaan dipetakan melalui Alias ​​atau mod_userdir.

2 papo Jan 28 2017 at 16:58

Jika Anda berencana untuk menulis lebih dari satu baris aturan dalam .htacesss,
jangan pernah berpikir untuk mencoba salah satu metode perbaikan panas tersebut untuk men- debugnya .

Saya telah menyia-nyiakan hari untuk menetapkan banyak aturan, tanpa umpan balik dari LOG, hanya untuk akhirnya menyerah.
Saya mendapatkan Apache di PC saya, menyalin seluruh situs ke HDD-nya, dan menyelesaikan seluruh aturan yang ditetapkan, menggunakan log, sangat cepat.
Kemudian saya meninjau kembali aturan lama saya, yang telah berhasil. Saya melihat mereka tidak benar-benar melakukan apa yang diinginkan. Sebuah bom waktu, dengan alamat yang sedikit berbeda.

Ada begitu banyak kesalahan dalam aturan penulisan ulang, ini sama sekali bukan logika yang lurus.
Anda dapat mengaktifkan dan menjalankan Apache dalam sepuluh menit, ini 10MB, lisensi yang bagus, * NIX / WIN / MAC siap, bahkan tanpa menginstal.
Juga, periksa baris header server Anda dan dapatkan versi Apache yang sama dari arsip mereka jika sudah lama. OP saya masih di 2.0; banyak hal tidak didukung.

1 Gruber Sep 04 2015 at 12:39

Saya akan meninggalkan ini di sini, mungkin detail yang jelas, tetapi membuat saya membenturkan kepala saya selama berjam-jam: hati-hati menggunakan %{REQUEST_URI}karena apa yang dikatakan @Krist van Besien dalam jawabannya benar-benar benar, tetapi tidak untuk string REQUEST_URI , karena keluaran dari ini TestString dimulai dengan a /. Jadi berhati-hatilah:

RewriteCond %{REQUEST_URI} ^/assets/$  
                            ^
                            | check this pesky fella right here if missing
unloco Oct 14 2013 at 11:54

(Mirip dengan ide Doin) Untuk menunjukkan apa yang cocok, saya menggunakan kode ini

$keys = array_keys($_GET);
foreach($keys as $i=>$key){ echo "$i => $key <br>";
}

Simpan ke r.php di root server dan kemudian lakukan beberapa tes di .htaccess
Misalnya, saya ingin mencocokkan url yang tidak dimulai dengan awalan bahasa

RewriteRule ^(?!(en|de)/)(.*)$ /r.php?$1&$2 [L] #$1&$2&...
RewriteRule ^(.*)$ /r.php?nomatch [L] #report nomatch and exit
Aurovrata Jan 15 2020 at 16:27

seperti yang ditunjukkan oleh @JCastell, penguji online melakukan pekerjaan yang baik dalam menguji pengalihan individu terhadap file .htaccess. Namun, yang lebih menarik adalah terpapar api yang dapat digunakan untuk menguji batch daftar url menggunakan objek json. Namun, untuk membuatnya lebih berguna, saya telah menulis file skrip bash kecil yang menggunakan curl dan jq untuk mengirimkan daftar url dan mengurai respons json menjadi output berformat CSV dengan nomor baris dan aturan yang cocok di file htaccess bersama dengan url yang diarahkan ulang, membuatnya sangat berguna untuk membandingkan daftar url di spreadsheet dan dengan cepat menentukan aturan mana yang tidak berfungsi.