<-
Apache > HTTP Sunucusu > Belgeleme > Sürüm 2.5 > Rewrite

mod_rewrite ile Yeniden Yönlendirme ve Yeniden Eşleme

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn 

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.

Bu örneklerin birçoğunun sizin sunucu yapılandırmanızda değişiklik yapılmadan çalışmayacağını unutmayın; bu nedenle örnekleri yapılandırmanıza kopyalayıp yapıştırmak yerine anlamanız önemlidir.

Ayrıca bakınız:

top

Eskiden Yeniye (dahili)

Açıklama:

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

Çözüm:

Eski URL'yi aşağıdaki kuralla dahili olarak yenisine yeniden yazıyoruz:

RewriteEngine  on
RewriteRule    "^/foo\.html$"  "/bar.html" [PT]
top

Eskiden Yeniye Yeniden Yazma (harici)

Açıklama:

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.

Çözüm:

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]
Tartışma

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"
top

Başka Bir Sunucuya Taşınan Kaynak

Açıklama:

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.

Çözüm:

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/"
top

Statikten Devingene

Açıklama:

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?

Çözüm:

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]
top

Dosya Uzantısı Değişikliği için Geriye Dönük Uyumluluk

Açıklama:

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?

Çözüm:

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>
Tartışma

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.

top

Kurallı Konak Adları

Açıklama:
Bu kuralın amacı, aynı siteye erişmek için kullanılabilecek diğer konak adları yerine belirli bir konak adının kullanılmasını zorlamaktır. Örneğin, example.com yerine www.example.com kullanılmasını zorlamak istiyorsanız aşağıdaki tarifin bir varyantını kullanabilirsiniz.
Çözüm:

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.

top

Birden Fazla Dizinde Sayfa Arama

Açıklama:

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.

Çözüm:

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]
top

Coğrafi Olarak Dağıtılmış Sunuculara Yönlendirme

Açıklama:

Web sitemizin çok sayıda yansısı var ve insanları bulundukları ülkedeki yansıya yönlendirmek istiyoruz.

Çözüm:

İ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##

Tartışma
Bu kural kümesi, 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.

top

Kurallı URL'ler

Açıklama:

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.

Çözüm:

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]
Tartışma:
Bu gerçekten Redirect veya RedirectMatch yönergeleriyle gerçekleştirilmelidir:
RedirectMatch "^/(puppies|canines)/(.*)" "/dogs/$2"
top

Taşınmış DocumentRoot

Açıklama:

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:

Çözüm:

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

top

Yedek Kaynak

Açıklama:
Belirli bir dizine gelen tüm istekleri, bir resim veya css dosyası gibi mevcut bir kaynağa gitmesi gerekenler dışında tek bir kaynağın (örneğin index.php gibi belirli bir dosyanın) işlemesini istiyorsunuz.
Çözüm:

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.

top

Sorgu Dizgesini Yeniden Yazma

Açıklama:
Bir sorgu dizgesinden belirli bir değeri yakalamak ve onu değiştirmek veya URL'nin başka bir bileşenine dahil etmek istiyorsunuz.
Çözümler:

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.

  • Bu çözüm eşleşen anahtarı ve değeri kaldırır:
    # mykey=??? öğesini kaldır
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteRule "(.*)"            "$1?%1%3"
  • Bu çözüm, yakalanan değeri URL değiştirmesinde kullanır ve sonuna '?' ekleyerek orijinal sorgu dizgesinin geri kalanını atar:
    # Sorgu dizgesinden PATH_INFO'ya kopyala
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteRule "(.*)"            "$1/products/%2/?" [PT]
  • Bu çözüm, yakalanan değeri sonraki bir koşulda kontrol eder:
    # Sorgu dizgesindeki mykey değerini yakala
    RewriteCond "%{QUERY_STRING}" "(.*(?:^|&))mykey=([^&]*)&?(.*)&?$"
    RewriteCond "%2"              !=not-so-secret-value
    RewriteRule "(.*)"            "-" [F]
  • Bu çözüm, önceki çözümlerin tersini gösterir: yol bileşenlerini (belki PATH_INFO) URL'den sorgu dizgesine kopyalar.
    # İstenen URL /products/kitchen-sink olabilir ve betik
    # /path?products=kitchen-sink bekler.
    RewriteRule "^/?path/([^/]+)/([^/]+)" "/path?$1=$2" [PT]

Mevcut Diller:  de  |  en  |  es  |  fr  |  ja  |  ko  |  tr  |  zh-cn