RewriteRule'imin bulunduğu yere bağlı olarak neden çift eğik çizgi alıyorum?


9

Tüm www isteklerini www olmayan URL'lere yönlendirmek için aşağıdaki kodu kullanıyorum:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

Bu, web sitemin kökündeki bir .htaccess dosyası içinde harika çalışıyor.
Örneğin,
www.example.com -> example.com/
www.example.com/ -> example.com/
www.example.com/diğer_sayfa -> example.com/other_page

Ancak, aynı kodu VirtualHost yapılandırmamın içine taşırsam, yeniden yazılan URL'ler bir çift eğik çizgi içerir.
www.example.com -> example.com//
www.example.com/ -> example.com//
www.example.com/diğer_sayfa -> example.com//other_sayfa

Yeniden yazma kuralından eğik çizgiyi kaldırarak düzelttim:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

Ama bunun nedenini anlayamıyorum. Nedenini bilen var mı?

Yanıtlar:


10

Anladığım kadarıyla, .htaccess dosyalarında, kuralınızdaki mod_rewrite işlemlerinin gerçekleştirdiği dize, .htaccess dosyasının bulunduğu dizine göreli olduğundan, başında bir / olmayacaktır.

VirtualHost girdisinde, işlediği dize sunucunun kök dizininde mutlaktır ve bu nedenle / öğesini içerir.

Bu mod_rewrite'ın nasıl çalıştığı konusunda ince farklar yaratır.

İşte benzer bir sorunu ve çözümü olan biri:

http://forum.modrewrite.com/viewtopic.php?p=56322&sid=77f72967f59200b5b5de174440234c3a

Bu, her iki durumda da doğru şekilde kaçmamı hatırladığımı varsayarak çalışmalıdır:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^\/?(.*?)$ http://example.com/$1 [R=301,L]

Teşekkürler! Şimdi en azından nedenini anlıyorum. Ancak, bu, herhangi bir nedenden dolayı, orijinal sorumda gösterdiğim gibi 1 $ 'dan önce / öncesini kaldırmaktan daha mı iyi?
davekaro

1
Daha iyisi ya da daha kötüsü, bu, bağlam farklılıklarını ele almak için her seferinde düzenlemek zorunda kalmadan VirtualHost'un .htaccess'i arasında geçiş yapabileceğiniz bir bloktur. Yolunuz sizin için çalışıyorsa, ona sadık kalın! :)
Neobyte

Ah bu doğru - yönteminiz hem .htaccess hem de VirtualHost içinde çalışacaktır. Bu daha iyi IMO yapar :)
davekaro

4
@Davekaro ile aynı problemi yaşadım ve çözümünüzü denedim. Son satır benim için işe yaramadı. RewriteRule ^/?(.*)$ http://example.com/$1 [R=301,L]hile yaptı.
Kenny Rasschaert

2

Bunun nedeni, ilk eğik çizgiyi yakaladığınız (.*)ve daha sonra yeni konumda bir eğik çizgi daha uyguladığınızdır /$1. Daha önce olmadı, çünkü mod_rewrite, sunucu başına bağlamın aksine dizin başına bağlamda çalışırken biraz farklı davranıyor.

İsteğe bağlı olarak eğik çizgiyi önceden boşaltarak bunu önleyebilirsiniz. Ek olarak, fazla alanlarınızla boş bir VirtualHost'ta RedirectMatch'i kullanabilirsiniz, bu da biraz daha az işleme oluşturur ve daha temiz görünebilir.

<VirtualHost *>
ServerName example.com
ServerAlias other.example.com
..
RedirectMatch permanent ^/?(.*) http://example.com/$1
</VirtualHost>


Güzel. RedirectMatch yaklaşımını seviyorum. Muhtemelen bununla devam edeceğim çünkü gerçekten yapmak istediğim bir yönlendirme.
davekaro

1

Bu yazıyı bütünlük için ekliyorum.

Apaçi belgeleri bu davranış çok iyi ortaya çıkar ve 'RewriteBase' direktifi var olduğunu nedenidir açıklıyor.

Sadece .htaccess dosyanıza 'RewriteBase' yönergesini dahil etmek istediğiniz sonucu elde etmelidir.

Misal:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

Apache 2.2 mod_rewrite belgelerinden:

RewriteBase yönergesi dizin başına yeniden yazma işlemleri için temel URL'yi açıkça ayarlar.

Temel kuralım .htaccess dosyalarında neredeyse her zaman 'RewriteBase' kullanmak ve Apache yapılandırmasında kullanmak değil.


0

Bu sorunu çözmek için zamanım olmadı, bu yüzden // / / :)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ http://domain.com [R=301,L]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.