Bir site taşındığında, alan adı değiştiğinde ya da SSL sertifikası kurulduktan sonra tarayıcının hâlâ eski adresi (http:// veya www. olmadan) açması yaygın bir sorundur. Arama motorları aynı içeriğe iki farklı adresten erişilebildiğinde bunu ayrı sayfalar gibi değerlendirebilir, ziyaretçi ise güvenli olmayan bağlantı uyarısıyla karşılaşabilir. Apache çalıştıran bir sunucuda bu tür yönlendirmeleri merkezi bir yerde, tek dosyayla çözmenin standart yolu .htaccess dosyasıdır.
.htaccess dosyası nedir ve Apache onu ne zaman okur?
.htaccess, bulunduğu dizin ve altındaki tüm alt dizinler için geçerli olan, dizin bazlı bir Apache yapılandırma dosyasıdır. Ana yapılandırma dosyasına (httpd.conf) dokunmadan yönlendirme, erişim ve yeniden yazma kuralları tanımlamayı sağlar. Ana yapılandırmaya erişiminizin olmadığı paylaşımlı hosting ortamlarında bu, yönlendirme kuralı tanımlamanın pratikte tek yoludur; ayrıca değişiklik için sunucuyu yeniden başlatmaya gerek yoktur, çünkü Apache dosyayı her istekte yeniden okur.
Bu rahatlığın iki ön koşulu vardır. Birincisi, yönlendirme kurallarını çalıştıran mod_rewrite modülünün sunucuda etkin olması gerekir (Debian/Ubuntu'da sudo a2enmod rewrite ile açılır). İkincisi, ilgili <Directory> veya <VirtualHost> bloğunda AllowOverride All tanımlı olmalıdır. Sunucu AllowOverride None ile yapılandırılmışsa Apache .htaccess dosyasını tamamen yok sayar; kurallar hata vermeden, sessizce devre dışı kalır — bu yüzden "kurallar hiç çalışmıyor" şikâyetlerinin çoğu aslında bu ayardan kaynaklanır.
Kolaylığın bir bedeli de vardır: Apache, istenen dosyaya giden her dizin kademesinde bir .htaccess olup olmadığını denetler ve bulduğu her dosyayı her istekte yeniden ayrıştırır — sonuç önbelleğe alınmaz. Ana sunucu yapılandırmasına erişiminizin olduğu bir VPS veya dedicated sunucuda aynı kuralları doğrudan <VirtualHost> bloğuna yazmak daha hızlıdır, çünkü Apache dizin ağacını .htaccess için taramak zorunda kalmaz. Paylaşımlı hostingde ise zaten başka seçenek yoktur.
mod_rewrite temelleri: RewriteEngine, RewriteCond, RewriteRule
Bir .htaccess dosyasında yönlendirme kuralları yazmadan önce modülü açık olarak işaretlemeniz gerekir: RewriteEngine On. Bundan sonraki her RewriteRule satırı, isteğin URI'sini bir desenle eşleştirip gerekirse başka bir adrese yönlendirir. RewriteCond ise kendisinden sonra gelen tek bir RewriteRule için ön koşul tanımlar; koşul sağlanmazsa o kural atlanır. Kurallar dosyada yukarıdan aşağıya sırayla işlenir, bu yüzden sıralama sonucu doğrudan etkiler.
%{HTTPS}— bağlantının SSL üzerinden gelip gelmediğinion/offolarak verir, HTTPS zorlamanın temelidir.%{HTTP_HOST}— istemcinin tarayıcısına yazdığı alan adı (www dahil ya da hariç).%{REQUEST_URI}— sorgu dizesi hariç, istenen yol (ör./urunler/kalem).%{REQUEST_FILENAME}— isteğe karşılık gelen dosya sisteminde tam yol; genelde dosya/dizin var mı diye kontrol için kullanılır.[L]bayrağı — bu kuraldan sonra başka kural işlenmesin.[R=301]bayrağı — kalıcı yönlendirme (arama motorları eski adresi yeniyle günceller).[NC]bayrağı — desen eşleştirmesini büyük/küçük harfe duyarsız yapar.
Örnek kurallar: HTTPS zorlama, www yönetimi ve gzip sıkıştırma
Aşağıdaki blok üç yaygın senaryoyu bir arada gösterir: tüm trafiği HTTPS'e taşımak, adresleri www. ön ekiyle standartlaştırmak ve metin tabanlı yanıtları gzip ile sıkıştırmak.
<IfModule mod_rewrite.c>
RewriteEngine On
# HTTPS'e zorla
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# www ekle
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# Dizin listelemeyi kapat
Options -Indexes
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/css text/xml text/javascript application/javascript application/json application/xml
</IfModule>
İlk blok, %{HTTPS} değişkeni off olduğunda isteği aynı host ve yol ile https:// öneki altında yeniden oluşturur. İkinci blok, host adı www. ile başlamıyorsa (!^www\.) başına ekler. Tersini istiyorsanız — yani www. her zaman kaldırılsın — koşulu RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] şeklinde yazıp hedefte %1 yakalama grubunu kullanırsınız: RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]. Buradaki %1, RewriteRule deseninden değil, bir önceki RewriteCond satırındaki parantezden gelir; RewriteRule'ün kendi yakalama grupları için ise $1 kullanılır.
Son blok mod_deflate modülünü kullanır ve belirtilen MIME türlerindeki yanıtları (CSS, JavaScript, düz metin, JSON, XML gibi) sunucudan gönderilmeden önce sıkıştırır. Bu, tarayıcıya giden veri boyutunu küçültür; kuralın etkili olması için sunucuda mod_deflate modülünün yüklü ve etkin olması gerekir. Zaten sıkıştırılmış biçimde gelen görsel ve video dosyalarını bu listeye eklemenin ek bir faydası yoktur, hatta gereksiz CPU yükü oluşturabilir.
.htaccess dosyasının bir kopyasını alın. Bir satırdaki sözdizimi hatası siteyi tamamen erişilemez hale getirebilir; kopya sayesinde dosyayı saniyeler içinde eski haline döndürebilirsiniz.Sık yapılan hatalar
| Belirti | Olası neden | Çözüm |
|---|---|---|
| Sonsuz yönlendirme döngüsü | Ters proxy veya yük dengeleyici arkasındaki sunucuda %{HTTPS} her zaman off görünür; HTTPS kuralı isteği tekrar tekrar yönlendirir | Proxy'nin ilettiği X-Forwarded-Proto başlığını kontrol eden bir koşul eklemek gerekir; doğrudan Apache SSL kullanan kurulumlarda bu sorun görülmez |
| Kurallar hiç çalışmıyor, adres eski haliyle açılıyor | AllowOverride None ayarlı ya da mod_rewrite etkin değil | Sunucu yöneticisinden ilgili <Directory> bloğunda AllowOverride All istenir; kendi sunucunuzdaysa a2enmod rewrite ile modül açılır |
| 500 Internal Server Error | Dosyada sözdizimi hatası: kapanmamış <IfModule> etiketi, hatalı bayrak yazımı veya yanlış escape edilmiş nokta/eğik çizgi | Apache hata günlüğü (error_log) satır numarasını verir; dosyayı o satırdan itibaren gözden geçirin |
| Gzip etkin ama boyut küçülmüyor | mod_deflate sunucuda yüklü değil ya da ilgili MIME türü listeye eklenmemiş | Modülün etkin olduğunu sunucu yöneticinizle doğrulayın; yanıt başlıklarında Content-Encoding: gzip olup olmadığına bakın |
Bu hataların ortak noktası, tek bir eksik koşulun ya da yanlış sıralamanın kuralın tamamını işlevsiz bırakabilmesidir. HTTPS ve www kurallarını aynı dosyada birlikte kullanırken sırayı korumak (önce protokol, sonra host normalizasyonu) ve her RewriteRule'ün doğru RewriteCond ile eşleştiğinden emin olmak, döngü ve yanlış yönlendirme riskini büyük ölçüde azaltır.
Kuralları elle mi yazmalı, oluşturucu mu kullanmalı?
Sözdizimini bir kez öğrendikten sonra tek bir kuralı elle yazmak zor değildir. Zorluk, HTTPS zorlama, www normalizasyonu, trailing slash temizliği ve gzip sıkıştırmayı aynı dosyada doğru sırayla ve doğru <IfModule> blokları içinde bir araya getirmektir — özellikle escape edilmesi gereken nokta (\.) gibi ayrıntılar ilk denemede gözden kolayca kaçar. Seçenekleri işaretleyip hazır, kopyalamaya uygun bir dosya almak isteyenler için KEYDAL'ın .htaccess oluşturucusu bu kombinasyonu otomatik olarak üretir.
HTTPS zorlama, www yönlendirmesi, trailing slash temizliği ve gzip sıkıştırmayı kutucukları işaretleyerek tek dosyada oluşturun.