Apache HTTP Sunucusu Sürüm 2.5

Bu belge, mod_rewrite
başvuru belgelerini tamamlar.
İstekleri yeniden yönlendirmek ve yeniden eşlemek için
mod_rewrite modülünü nasıl kullanabileceğinizi
açıklar. Her birinin nasıl çalıştığının ayrıntılı açıklamalarını
içeren birçok mod_rewrite kullanım örneği
sunar.
Eskiden Yeniye (dahili)
Eskiden Yeniye Yeniden Yazma (harici)
Başka Bir Sunucuya Taşınan Kaynak
Statikten Devingene
Dosya Uzantısı Değişikliği için Geriye Dönük Uyumluluk
Kurallı Konak Adları
Birden Fazla Dizinde Sayfa Arama
Coğrafi Olarak Dağıtılmış Sunuculara Yönlendirme
Kurallı URL'ler
Taşınmış DocumentRoot
Yedek Kaynak
Sorgu Dizgesini Yeniden Yazmafoo.html sayfasını yakın zamanda
bar.html olarak yeniden adlandırdığımızı ve şimdi
geriye dönük uyumluluk için eski URL'yi sağlamak istediğimizi
varsayalım. Ancak eski URL kullanıcılarının sayfanın yeniden
adlandırıldığını fark etmemesini istiyoruz - yani adresin
tarayıcılarında değişmesini istemiyoruz.
Eski URL'yi aşağıdaki kuralla dahili olarak yenisine yeniden yazıyoruz:
RewriteEngine on RewriteRule "^/foo\.html$" "/bar.html" [PT]
Yine foo.html sayfasını yakın zamanda
bar.html olarak yeniden adlandırdığımızı ve şimdi
geriye dönük uyumluluk için eski URL'yi sağlamak istediğimizi
varsayalım. Ancak bu sefer eski URL kullanıcılarının yeni URL
hakkında bilgilendirilmesini istiyoruz, yani tarayıcılarının
Konum alanı da değişmeli.
Tarayıcının ve dolayısıyla kullanıcının görünümünün değişmesini sağlayan yeni URL'ye bir HTTP yönlendirmesi zorluyoruz:
RewriteEngine on RewriteRule "^/foo\.html$" "bar.html" [R]
Bu örnekte, dahili örneğin
aksine, basitçe Redirect yönergesini kullanabiliriz. Önceki
örnekte mod_rewrite, yönlendirmeyi istemciden
gizlemek için kullanılmıştı:
Redirect "/foo.html" "/bar.html"
Bir kaynak başka bir sunucuya taşındıysa, insanlar yer imlerini güncellerken URL'lerin eski sunucuda bir süre daha çalışmasını isteyebilirsiniz.
Bu URL'leri yeni sunucuya yönlendirmek için
mod_rewrite kullanabilirsiniz, ancak Redirect
veya RedirectMatch yönergesini kullanmayı da
düşünebilirsiniz.
#mod_rewrite ile RewriteEngine on RewriteRule "^/docs/(.+)" "http://new.example.com/docs/$1" [R,L]
#RedirectMatch ile RedirectMatch "^/docs/(.*)" "http://new.example.com/docs/$1"
#Redirect ile Redirect "/docs/" "http://new.example.com/docs/"
Statik bir sayfa olan foo.html'yi devingen bir
varyant olan foo.cgi'ye tarayıcı/kullanıcı fark
etmeden sorunsuz bir şekilde nasıl dönüştürebiliriz?
URL'yi CGI betiğine yeniden yazar ve işleyiciyi
cgi-script olarak zorlayarak bir CGI programı
olarak yürütülmesini sağlarız. Böylece
/~quux/foo.html isteği dahili olarak
/~quux/foo.cgi'nin çağrılmasına yol açar.
RewriteEngine on RewriteBase "/~quux/" RewriteRule "^foo\.html$" "foo.cgi" [H=cgi-script]
document.YYYY'den document.XXXX'e
geçiş yaptıktan sonra, örneğin bir dizi .html
dosyasını .php'ye çevirdikten sonra URL'leri nasıl
geriye dönük uyumlu (sanal olarak hâlâ mevcut) yapabiliriz?
URL, yeni uzantılı hedef dosya mevcutsa ve eski uzantılı orijinal dosya mevcut değilse eski uzantıdan yeni uzantıya yeniden yazılır. Aksi takdirde URL değiştirilmeden bırakılır.
# document.html'yi document.php'ye yeniden yazma
# için geriye dönük uyumluluk kural kümesi
# yalnızca document.php varsa
<Directory "/var/www/htdocs">
RewriteEngine on
RewriteBase "/var/www/htdocs"
RewriteCond "$1.php" -f
RewriteCond "$1.html" !-f
RewriteRule "^(.*).html$" "$1.php"
</Directory>
Bu örnek, mod_rewrite modülünün genellikle
gözden kaçan bir özelliğini kullanır: kural kümesinin yürütme
sırasından yararlanır. Özellikle, mod_rewrite
RewriteCond yönergelerini değerlendirmeden önce RewriteRule'un
sol tarafını değerlendirir. Sonuç olarak, RewriteCond yönergeleri
değerlendirildiğinde $1 zaten tanımlanmış olur. Bu, aynı temel
dosya adını kullanarak orijinal (document.html) ve
hedef (document.php) dosyaların varlığını
sınamamıza olanak tanır.
Bu kural kümesi dizin başına bağlamda (bir <Directory>
bloğunda veya bir .htaccess dosyasında) kullanılmak üzere
tasarlanmıştır; böylece -f kontrolleri doğru dizin
yoluna bakar. Çalıştığınız dizin tabanını belirtmek için bir
RewriteBase yönergesi
ayarlamanız gerekebilir.
Bunu çözmenin en iyi yolu mod_rewrite kullanmak
değil, kurallı olmayan konak ad(lar)ı için bir sanal konağa yerleştirilmiş
Redirect yönergesini
kullanmaktır.
<VirtualHost *:80> ServerName undesired.example.com ServerAlias example.com notthis.example.com Redirect "/" "http://www.example.com/" </VirtualHost> <VirtualHost *:80> ServerName www.example.com </VirtualHost>
Bunu alternatif olarak <If> yönergesini kullanarak da
gerçekleştirebilirsiniz: (2.4 ve sonrası)
<If "%{HTTP_HOST} != 'www.example.com'">
Redirect "/" "http://www.example.com/"
</If>
Veya örneğin, sitenizin bir bölümünü HTTPS'ye yönlendirmek için şunları yapabilirsiniz:
<If "%{SERVER_PROTOCOL} != 'HTTPS'">
Redirect "/admin/" "https://www.example.com/admin/"
</If>
Herhangi bir nedenle hâlâ mod_rewrite kullanmak
istiyorsanız - örneğin buna daha büyük bir RewriteRules kümesiyle
birlikte ihtiyaç duyuyorsanız - aşağıdaki tariflerden birini
kullanabilirsiniz.
80 dışında bir bağlantı noktasında çalışan siteler için:
RewriteCond "%{HTTP_HOST}" "!^www\.example\.com" [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteCond "%{SERVER_PORT}" "!^80$"
RewriteRule "^/?(.*)" "http://www.example.com:%{SERVER_PORT}/$1" [L,R,NE]
80 bağlantı noktasında çalışan bir site için
RewriteCond "%{HTTP_HOST}" "!^www\.example\.com" [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.example.com/$1" [L,R,NE]
Bunu tüm alan adları için genel olarak yapmak istiyorsanız - yani tüm olası example.com değerleri için example.com'u www.example.com'a yönlendirmek istiyorsanız - aşağıdaki tarifi kullanabilirsiniz:
RewriteCond "%{HTTP_HOST}" "!^www\." [NC]
RewriteCond "%{HTTP_HOST}" "!^$"
RewriteRule "^/?(.*)" "http://www.%{HTTP_HOST}/$1" [L,R,NE]
Bu kural kümeleri, ana sunucu yapılandırma dosyanızda veya
sunucunun DocumentRoot
dizinine yerleştirilen bir .htaccess dosyasında
çalışacaktır.
Belirli bir kaynak birkaç yerden birinde olabilir ve istendiğinde bu yerlerde kaynağı aramak istiyoruz. Belki yakın zamanda dizin yapımızı yeniden düzenledik ve içeriği birkaç konuma böldük.
Aşağıdaki kural kümesi, kaynağı bulmak için iki dizinde arama yapar ve hiçbirinde bulamazsa istenen konumdan sunmayı dener.
RewriteEngine on
# önce dir1/ içinde bulmayı dene
# ...ve bulunursa dur ve mutlu ol:
RewriteCond "%{DOCUMENT_ROOT}/dir1/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/dir1/$1" [L]
# sonra dir2/ içinde bulmayı dene
# ...ve bulunursa dur ve mutlu ol:
RewriteCond "%{DOCUMENT_ROOT}/dir2/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/dir2/$1" [L]
# yoksa diğer Alias veya ScriptAlias yönergeleri vb. için devam et.
RewriteRule "^" "-" [PT]
Web sitemizin çok sayıda yansısı var ve insanları bulundukları ülkedeki yansıya yönlendirmek istiyoruz.
İstemcinin konak adına bakarak hangi ülkeden geldiklerini belirliyoruz. IP adreslerini çözümleyemezsek öntanımlı bir sunucuya geri dönüyoruz.
Kullanmak istediğimiz sunucuların listesini oluşturmak için
bir RewriteMap
yönergesi kullanacağız.
HostnameLookups on
RewriteEngine on
RewriteMap multiplex "txt:/path/to/map.mirrors"
RewriteCond "%{REMOTE_HOST}" "([a-z]+)$" [NC]
RewriteRule "^/(.*)$" "${multiplex:%1|http://www.example.com/}$1" [R,L]
## map.mirrors -- Çoğullama Eşlem Dosyası
de http://www.example.de/
uk http://www.example.uk/
com http://www.example.com/
##EOF##
HostNameLookups yönergesinin
on olarak ayarlanmasına dayanır; bu da önemli bir
performans etkisi olabilir.RewriteCond
yönergesi, istemcinin konak adının son bölümünü - ülke kodunu -
yakalar ve ardından gelen RewriteRule bu değeri eşlem dosyasında
uygun yansı konağını aramak için kullanır.
Bazı web sunucularında bir kaynak için birden fazla URL bulunur. Genellikle kurallı URL'ler (gerçekten kullanılan ve dağıtılan) ve kısayollar, dahili URL'ler vb. vardır. Kullanıcı istekle hangi URL'yi sağlamış olursa olsun, sonunda tarayıcı adres çubuğunda kurallı olanı görmelidir.
Tüm kurallı olmayan URL'leri tarayıcının Konum görünümünde
düzeltmek ve sonraki tüm istekler için harici bir HTTP
yönlendirmesi yapıyoruz. Aşağıdaki örnek kural kümesinde
/puppies ve /canines yollarını
kurallı /dogs ile değiştiriyoruz.
RewriteRule "^/(puppies|canines)/(.*)" "/dogs/$2" [R]
RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"
DocumentRoot ¶Genellikle web sunucusunun DocumentRoot dizini doğrudan
"/" URL'siyle ilişkilidir. Ancak çoğu zaman bu veriler
gerçekten en üst düzey önceliğe sahip değildir. Örneğin, siteye ilk
giren ziyaretçilerin belirli bir /about/ alt dizinine
yönlendirilmesini isteyebilirsiniz. Bu, aşağıdaki kural kümesi
kullanılarak gerçekleştirilebilir:
/ URL'sini /about/ adresine
yönlendiriyoruz:
RewriteEngine on RewriteRule "^/$" "/about/" [R]
Bunun RedirectMatch
yönergesi kullanılarak da ele alınabileceğini unutmayın:
RedirectMatch "^/$" "http://example.com/about/"
Ayrıca örneğin yalnızca kök URL'yi yeniden yazdığını unutmayın.
Yani http://example.com/ isteğini yeniden yazar ancak
http://example.com/page.html isteğini yeniden yazmaz.
Belge kökünüzü gerçekten değiştirdiyseniz - yani tüm içeriğiniz
aslında o alt dizindeyse - DocumentRoot yönergesini değiştirmek veya
tüm içeriği bir dizin yukarı taşımak, URL'leri yeniden yazmaktan
çok daha tercih edilir.
2.2.16 sürümünden itibaren bunun için FallbackResource yönergesini
kullanmalısınız:
<Directory "/var/www/my_blog"> FallbackResource index.php </Directory>
Ancak Apache'nin önceki sürümlerinde veya ihtiyaçlarınız bundan daha karmaşıksa, aynı şeyi gerçekleştirmek için aşağıdaki yeniden yazma kümesinin bir varyasyonunu kullanabilirsiniz:
<Directory "/var/www/my_blog">
RewriteBase "/my_blog"
RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-f
RewriteCond "/var/www/my_blog/%{REQUEST_FILENAME}" !-d
RewriteRule "^" "index.php" [PT]
</Directory>
Diğer taraftan, istenen URI'yi index.php'ye sorgu dizgesi argümanı olarak geçirmek isterseniz, o RewriteRule'u şununla değiştirebilirsiniz:
RewriteRule "(.*)" "index.php?$1" [PT,QSA]
Bu kural kümelerinin bir .htaccess dosyasında ve
bir <Directory> bloğunda da kullanılabileceğini unutmayın.
Bu bölümdeki çözümlerin birçoğu aynı koşulu kullanır; bu koşul eşleşen değeri %2 geri başvurusunda bırakır. %1 sorgu dizgesinin başlangıcıdır (ilgili anahtara kadar) ve %3 geri kalanıdır. Bu koşul, esneklik ve değiştirmelerde çift '&&' oluşmasını önlemek için biraz karmaşıktır.
# mykey=??? öğesini kaldır
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteRule "(.*)" "$1?%1%3"
# Sorgu dizgesinden PATH_INFO'ya kopyala
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteRule "(.*)" "$1/products/%2/?" [PT]
# Sorgu dizgesindeki mykey değerini yakala
RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
RewriteCond "%2" !=not-so-secret-value
RewriteRule "(.*)" "-" [F]
# İstenen URL /products/kitchen-sink olabilir ve betik # /path?products=kitchen-sink bekler. RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]