Apache’de Yönlendirme, URL’leri Değiştirme veya HTTP’yi HTTPS’ye Yönlendirme - Mod_Rewrite Kuralları Hakkında Bilmek İstediğiniz Her Şey


264

Bu, Apache'nin mod_rewrite hakkında Kanonik bir Soru .

Bir istek URL'sini değiştirmek veya kullanıcıları orijinal olarak istediklerinden farklı bir URL'ye yönlendirmek mod_rewrite kullanılarak yapılır. Bu gibi şeyler içerir:

  • HTTP’yi HTTPS’ye (veya bunun tersi yönde) değiştirmek
  • İsteği, artık yeni bir değiştirmede bulunmayan bir sayfaya değiştirme.
  • Bir URL biçimini değiştirme (? İd = 3433 - / id / 3433 gibi)
  • Tarayıcıya göre, yönlendiriciye göre, ayın ve güneşin altında olabilecek her şeye bağlı olarak farklı bir sayfa sunmak.
  • URL ile uğraşmak istediğiniz her şey

Mod_Rewrite Kuralları Hakkında Bilmek İstediğiniz Her Şey Fakat Sormaktan Korktunuz!

Mod_rewrite kurallarını yazma konusunda nasıl uzman olabilirim?

  • Mod_rewrite kurallarının temel formatı ve yapısı nedir?
  • Düzenli ifadelerin hangi biçimine / lezzetine sağlam bir kavrayışa ihtiyacım var?
  • Yeniden yazma kurallarını yazarken en sık karşılaşılan hatalar / tuzaklar nelerdir?
  • Mod_rewrite kurallarını test etmek ve doğrulamak için iyi bir yöntem nedir?
  • Bilmem gereken mod_rewrite kurallarının SEO veya performans etkileri var mı?
  • Mod_rewrite'ın iş için doğru araç gibi göründüğü ortak durumlar var mı?
  • Bazı yaygın örnekler nelerdir?

Kurallarınızı test edebileceğiniz bir yer

Htaccess tester web sitesi Kurallarınızla uğraşmak ve bunları test etmek için mükemmel bir yerdir. Hatta hata ayıklama çıktısını da gösterir, böylece neyin neyle eşleştiğini görebilirsiniz.


9
Bu sorunun arkasındaki fikir, daha düzenli kullanıcıları çıldırtan tüm sonsuz mod_rewrite soruları için yakın bir yol vermektir. Bu serverfault.com/questions/49765/how-does-subnetting-work adresinde alt ağda yapılanlara çok benzer .
Kyle Brandt

1
Ayrıca, bu soru hakkında gerçekten fazla oy almak istemiyorum , bunun yerine cevaba gitmeleri gerekiyor. Bunu yapmak istemiyorum çünkü posterin tüm mod_rewrite sorularını bitirmek için mod_rewrite cevabı olduğunu umduğum için tam kredi kazandığından emin olmak istiyorum .
Kyle Brandt,

4
Üzgünüm, soruyu aştım. ;-) Gerçekten mod-rewriteetiket aramalarının / filtrelerinin tepesinde (veya yakınında) görünmesi gerektiğini düşünüyorum .
Steven Pazartesi

Başka biri (tm) ortak kullanım durumlarını ele almalıdır. Onları adaleti yapacak kadar iyi tanımıyorum.
sysadmin1138

Belki de bu soru, yolu daha da kısaltmak için mod-rewrite etiketi wiki ile ilişkilendirilmelidir.
beldaz

Yanıtlar:


224

mod_rewrite sözdizimi sırası

mod_rewrite, işlemeyi etkileyen bazı özel sipariş kurallarına sahiptir. Herhangi bir şey yapılmadan önce, RewriteEngine Onyönergenin mod_rewrite işlemine başlamasından dolayı verilmesi gerekir. Bu, herhangi bir diğer yeniden yazma direktifinden önce olmalıdır.

RewriteCondönceki RewriteRule, bu ONE kuralını şartlı şart haline getirir. İzleyen herhangi bir RewriteRule, koşullara tabi değil gibi işlenecektir.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

Bu basit durumda, eğer HTTP yönlendiricisi serverfault.com'dan geliyorsa, blog isteklerini özel serverfault sayfalarına yönlendirin (biz sadece bu kadar özeliz). Ancak, yukarıdaki blok ekstra bir RewriteRule satırına sahipse:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

Tüm .jpg dosyaları, yalnızca buradan gelen bir yönlendirici olanlara değil, sunucuya özel sayfalara gider. Bu, açıkça bu kuralların nasıl yazıldığının amacı değildir. Birden fazla RewriteCond kuralıyla yapılabilir:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Ancak, muhtemelen bazı zorlu ikame sözdizimi ile yapılmalıdır.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Daha karmaşık RewriteRule, işleme için koşullamaları içerir. Son parantez, (html|jpg)RewriteRule öğesine ya htmlda ile eşleşmesini jpgve eşleşen dizgiyi yeniden yazılmış dizgede $ 2 olarak temsil etmesini söyler . Bu, mantıksal olarak önceki bloğun aynısıdır, iki RewriteCond / RewriteRule çifti ile, bunu dört yerine iki satırda yapar.

Birden çok RewriteCond satırı, dolaylı olarak ANDed'dir ve açıkça ORed olabilir. Hem ServerFault hem de Süper Kullanıcıdan gelen yönlendiricileri işlemek için (açık VEYA):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

ServerFault tarafından yönlendirilen sayfalara Chrome tarayıcılarla hizmet vermek için (örtük VE):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBaseayrıca, aşağıdaki RewriteRuledirektiflerin işlemlerini nasıl ele aldığını belirttiği için özeldir . .Htaccess dosyalarında çok kullanışlıdır. Eğer kullanılırsa, bir .htaccess dosyasındaki "RewriteEngine on" altındaki ilk yönerge olmalıdır. Bu örneği ele alalım:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Bu mod_rewrite'a şu anda kullandığı bu URL'nin fiziksel dizin yolu (/ home / $ Username / public_html / blog) yerine http://example.com/blog/ adresinden geldiğini ve buna göre davrandığını söylüyor . Bu nedenle RewriteRule, URL’deki "/ blog" dan sonra gelmeye başladığını düşünür. İşte iki farklı şekilde yazılmış aynı şey. Biri RewriteBase, diğeri olmadan:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Gördüğünüz gibi RewriteBase, yeniden yazma kurallarının web sitesi yolunu web sunucusu yerine içeriğe dönüştürmesini sağlar ; bu da onları bu tür dosyaları düzenleyenler için daha anlaşılır hale getirebilir. Ayrıca, estetik çekiciliği olan direktifleri kısaltabilirler.


RewriteRule eşleştirme sözdizimi

RewriteRule'un kendisi eşleşen dizeler için karmaşık bir sözdizimine sahiptir. Bayrakları ([PT] gibi şeyler) başka bir bölümde ele alacağım. Çünkü Sysadmins bir man-sayfa okuyarak daha sık örneklerle öğrendiği için örnekler vereceğim ve ne yaptıklarını açıklayacağım.

RewriteRule ^/blog/(.*)$    /newblog/$1

.*Yapı tek bir karakterle ( .) sıfır ya da daha fazla kez ( *). Parantez içine almak, $ 1 değişkeni ile eşleşen dizeyi sağlamasını söyler.

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

Bu durumda, ilk. * Parantez içine alınmadı, bu yüzden yeniden yazılmış dizgeye yazılmadı. Bu kural yeni blog sitesinde bir dizin seviyesini kaldırır. (/blog/2009/sample.html /newblog/sample.html olur).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

Bu durumda, ilk parantez ifadesi eşleşen bir grup oluşturur. Bu gerekli olmayan ve bu nedenle yeniden yazılmış dizgede kullanılmayan $ 1 olur.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

Bu durumda, yeniden yazılmış dizgede $ 1 kullanıyoruz.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

Bu kural, bir karakter aralığını belirten özel bir parantez sözdizimi kullanır . [0-9], 0 ile 9 arasındaki rakamlarla eşleşir. Bu özel kural 2000'den 2099'a kadar olan yılları idare eder.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

Bu, önceki kuralla aynı şeyi yapar, ancak {2} kısmı, önceki karakterle (bu durumda bir parantez ifadesi) iki kez eşleşmesini söyler.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

Bu durum, ikinci eşleşen ifadedeki küçük harflerle eşleşir ve olabildiğince çok karakter için bunu yapar. \.Yapı gerçek nokta değil, önceki örneklerde olduğu özel karakter olarak dönemini tedavi söyler. Yine de, dosya adının içinde tire varsa kırılır.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Bu dosya adlarını içinde kısa çizgilerle yakalar. Ancak, -parantez ifadelerinde özel bir karakter olduğu için , ifadedeki ilk karakter olmalıdır .

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Bu sürüm, herhangi bir dosya adını harf, sayı veya dosya adındaki -karakter ile hapseder . Bu, parantez ifadesinde birden çok karakter kümesini belirtme şeklinizdir.


RewriteRule bayrakları

Yeniden yazma kurallarındaki bayraklar çok sayıda özel anlam ve kullanım alanına sahiptir .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

Bayrak, [L]yukarıdaki ifadenin sonundadır. Virgülle ayrılmış olarak birden çok bayrak kullanılabilir. Bağlantılı belgeler her birini açıklar, ama yine de buradalar:

L = Son. Bu eşleştikten sonra RewriteRule'leri işlemeyi durdurun. Sipariş sayar!
C = Zincir. Bir sonraki RewriteRule'u işlemeye devam edin. Bu kural eşleşmezse, sonraki kural yürütülmez. Bunun üzerine daha sonra.
E = Çevre değişkenini ayarla. Apache, web sunucusu davranışını etkileyebilecek çeşitli çevresel değişkenlere sahiptir.
F = Yasak. Bu kural eşleşirse 403-Yasaklı hata verir.
G = Gitti. Bu kural eşleşirse 410-Gone hatası verir.
H = İşleyici. İsteği, belirtilen MIME türündemiş gibi ele alınmaya zorlar.
N = İleri Kuralı yeniden başlatmaya ve eşleşmeye zorlar. DİKKATLİ OL! Döngüler ortaya çıkabilir.
NC = Durum yok. verirjpghem jpg hem de JPG ile eşleşecek.
NE = Kaçış yok. Özel karakterlerin (.? # & Etc) onaltılık kod eşdeğerlerine yeniden yazılmasını önler.
NS = Alt istek yok. Sunucu tarafı içeriklerini kullanıyorsanız, bu eklenen dosyalarla eşleşmeleri önler.
P = Proxy. Kuralı mod_proxy tarafından ele alınmaya zorlar. Net olarak diğer sunuculardan içerik sağlayın, çünkü web sunucunuz onu alır ve yeniden sunar. Bu tehlikeli bir bayrak, kötü yazılmış bir web sunucusu sunucunuzu açık proxy'ye çevirecek ve Bu Kötü.
PT = Geçiş Yap. RewriteRule eşlemesindeki Alias ​​ifadelerini dikkate alın.
QSA = QSAppend. Orijinal dize bir sorgu içerdiğinde ( http://example.com/thing?asp=foo) Özgün sorgu dizesini yeniden yazılmış dizeye ekleyin. Normalde atılırdı. Dinamik içerik için önemlidir.
R = Yönlendirme. Belirtilen URL’ye bir HTTP yönlendirmesi sağlayın. Tam yönlendirme kodu da sağlayabilir [R = 303]. Çok benzer RedirectMatch, hangisi daha hızlı ve mümkün olduğunda kullanılmalıdır.
S = Atla. Bu kuralı atla.
T = Tip Döndürülen içeriğin MIME türünü belirtin. AddTypeDirektife çok benzer .

Bunun RewriteCondtek bir kural için nasıl geçerli olduğunu söylediğimi biliyor musun ? Bunu zincirleme yaparak halledebilirsin.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

İlk RewriteRule, Zincir bayrağına sahip olduğundan, ikinci yeniden yazma kuralı, ilk yapıldığında, yani önceki RewriteCond kuralı eşlendiğinde yürütülür. Eğer Apache düzenli ifadeler beyninizi incitirse işe yarar. Bununla birlikte, birinci bölümde işaret ettiğim hepsi bir arada yöntemi, optimizasyon açısından daha hızlı.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Bu, bayraklar aracılığıyla daha basit hale getirilebilir:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Ayrıca, bazı bayraklar RewriteCond için de geçerlidir. Özellikle, NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

"ServerFault.com" ile eşleşecek


9
Aferin. [dolgu]
EEAA

3
Çok güzel mod_rewriteve regex astar. +1.
Steven Pazartesi

3
O biliyor bazen faydalı olur RewriteCondaslında işlenir sonraRewriteRule eşleştirilir. "RewriteRule'den önceki RewriteCond, ONE kuralını koşulluya tabi kılar" dediğiniz üste yakın bir yerde "daha sonra" deyin. Regex'lerin Perl uyumlu normal ifadeler olduğunu söylemek isteyebilirsiniz. Ayrıca, "... RewriteRule 'nin string-start olduğunu düşünüyor ...' ta yabancı bir kesme işareti var ...
Dennis Williamson,

2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1ilk dizin bileşeniyle eşleşmiyor - yeniden yazmalar varsayılan olarak açgözlü. /.*/(.*) hem / 1 / (2) / ve / 1/2/3/4/5 / (6) / ile eşleşir, bu nedenle yalnızca FIRST yolunu bulmak için / [^ /] * / bileşen.
adaptr

1
@ sysadmin1138, bu cevabın iyi olduğunu düşünüyorum ancak bu bayrakların nasıl çalıştığı belli olmadığı için E, N, NS, P, PT ve S bayraklarını daha iyi
açıklarsanız daha iyi olabilir

39

Mod_rewrite kurallarının temel formatı ve yapısı nedir?

Bu noktalarda sysadmin1138'in mükemmel cevabını erteleyeceğim.

Düzenli ifadelerin hangi biçimine / lezzetine sağlam bir kavrayışa ihtiyacım var?

Sözdizimi sırasına, sysadmin1138 tarafından belirtilen sözdizimi eşleşmesi / normal ifadeler ve RewriteRule bayraklarına ek olarak, mod_rewrite'ın HTTP istek başlıklarına ve Apache'nin yapılandırmasına dayanarak Apache ortam değişkenlerini gösterdiğini de belirtdiğine inanıyorum.

Mod_rewrite için kullanılabilecek değişkenlerin kapsamlı bir listesi için AskApache'nin mod_rewrite Debug Tutorial'ı tavsiye ederim .

Yeniden yazma kurallarını yazarken en sık karşılaşılan hatalar / tuzaklar nelerdir?

RewriteRule ile ilgili sorunların çoğu, PCRE sözdiziminin yanlış anlaşılmasından / özel karakterlerden düzgün bir şekilde kaçamamaktan veya eşleştirme için kullanılan değişkenlerin içeriğine dair bir içgörü eksikliğinden kaynaklanır.

Tipik sorunlar ve önerilen sorun giderme:

  • 500 - Dahili Sunucu Hatası - Varsa , yapılandırma dosyalarındaki Windows taşıma denetimlerini kaldırın , mod_rewrite öğesinin etkinleştirildiğinden emin olun ( IfModulebu senaryoyu önlemek için yönergeleri koşullu sarın ), yönergenin sözdizimini kontrol edin, sorun tanımlanana kadar yönergeleri yorumlayın
  • Yönlendirme döngüsü - RewriteLog ve RewriteLogLevel'den yararlanın, sorun tanımlanana kadar yönergeleri yorumlayın

Mod_rewrite kurallarını test etmek ve doğrulamak için iyi bir yöntem nedir?

Öncelikle, eşleştirmeyi planladığınız ortam değişkenlerinin içeriğine bakın - eğer PHP kurulu ise, uygulamanıza şu bloğu eklemek kadar basit:

<?php
  var_dump($_SERVER);
?>

... sonra kurallarınızı yazın (tercihen bir geliştirme sunucusunda test etmek için) ve Apache ErrorLog dosyanızdaki tutarsız eşleşmeleri veya etkinlikleri not alın .

Daha karmaşık kurallar için, RewriteLogetkinliği bir dosyaya kaydetmek ve ayarlamak için mod_rewrite's direktifini kullanın.RewriteLogLevel 3

Bilmem gereken mod_rewrite kurallarının SEO veya performans etkileri var mı?

AllowOverride allApache'nin .htaccessdosyaları kontrol etmesi ve her isteği içeren yönergeleri ayrıştırması gerektiğinden sunucu performansını etkiler - mümkünse, tüm yönergeleri siteniz için VirtualHost yapılandırmasında saklayın veya .htaccessyalnızca kendilerine gereksinim duyan dizinler için geçersiz kılmaları etkinleştirin .

Google’ın Web Yöneticisi Yönergeleri, açıkça şunu belirtir: "Kullanıcılarınızı aldatmayın veya arama motorlarına, kullanıcılara gösterdiğinizden farklı olarak," gizleme "olarak adlandırılan kullanıcılardan daha fazla almayın." - arama motoru robotları için filtre uygulayan mod_rewrite yönergeleri oluşturmaktan kaçının.

Arama motoru robotları 1: 1 içeriği tercih ediyor: URI eşlemesi (içeriğe giden bağlantıları sıralamak için temeldir) - geçici yönlendirmeler oluşturmak için mod_rewrite kullanıyorsanız veya aynı içeriği birden fazla URI'da kullanıyorsanız, içinde bir kanuni URI belirtmeyi düşünün. HTML belgeleriniz.

Mod_rewrite'ın iş için doğru araç gibi göründüğü ortak durumlar var mı?

Bu, kendi başına büyük (ve potansiyel olarak çekişmeli) bir konudur - durumlara göre kullanımları ele almak (IMHO) ve önerilen kararların ihtiyaçlarına uygun olup olmadıklarına karar vermelerini isteyin.

Bazı yaygın örnekler nelerdir?

AskApache'nin mod_rewrite Püf Noktaları ve İpuçları , düzenli olarak açılan hemen hemen her kullanım durumunu kapsar, ancak, belirli bir kullanıcı için "doğru" çözüm, kullanıcının yapılandırmasının ve mevcut yönergelerin karmaşıklığına bağlı olabilir (bu nedenle genel bir iyi bir fikir olduğunu görmek için başka bir mod_rewrite'ı sorunu gündeme geliyor zaman) yerine bir kullanıcının sahip direktifleri.


AskApache bağlantısı için teşekkürler. Aradığım şey buydu!
sica07

AskApache palyaço ASF tarafından resmen desteklenmiyor. Söylediklerinin çoğu tartışmalı ya da açıkça yanlış.
adaptr

@adaptr Lütfen görünüşte bildiğiniz üstün kaynakları paylaşın.
danlefree,

"mod_rewrite'ın iş için doğru araç gibi göründüğü ortak durumlar ama değil mi?" - mod_rewrite zaten kullanılmadığı basit yönlendirmeler. Mod_alias Redirectveya RedirectMatchyerine kullanın. Ayrıca bakınız Apache dokümanları: mod_rewrite kullanılmadığı zaman
MrWhite

21

Birçok yönetici / geliştirici gibi ben de yıllardır yeniden yazma kurallarının karmaşıklığıyla mücadele ediyorum ve mevcut Apache dokümantasyonundan mutsuzum, bu yüzden mod_rewriteApache'nin geri kalanıyla nasıl çalıştığını ve etkileşime geçtiğinin altını çizecek kişisel bir proje olarak karar verdim Çekirdek, bu yüzden son birkaç ay boyunca strace, tüm bunlara cevap vermek için kaynak koduna + sondajı yapan test durumlarını enstrümanlandırıyorum .

Kural yeniden geliştiricisinin yeniden düşünmesi gereken bazı önemli yorumlar:

  • Yeniden bazı yönleri sunucu geneli, sanal konak, dizin .htaccess işleme ortak olan ancak
  • Bazı işlemler PerDir ( .htaccess) işlemenin aksine kök yapılandırma (sunucu yapılandırma, sanal ana bilgisayar ve dizin) için çok farklıdır .
  • Daha da kötüsü PerDir işleme, neredeyse İÇS REDIRECT döngüsünü ayırt etmeden tetikleyebildiği için, root konfigürasyon öğelerinin böyle bir PerDir işlemenin bunu tetikleyebileceğinin farkında olması gerekir.

Söyleyeceğim kadar büyüyordum ki, bu yüzden tekrar yazma kullanıcı topluluklarını iki kategoriye ayırmanız ve onları tamamen ayrı olarak ele almanız gerekiyor:

  • Apache yapılandırmasına kök erişimi olanlar . Bunlar genellikle bir uygulama tahsis edilmiş sunucusu / VM'si olan yönetici / geliştiricidir ve buradaki mesaj oldukça basittir: .htaccessmümkünse dosyaları kullanmaktan kaçının ; sunucunuzdaki veya vhost config'deki her şeyi yapın. Geliştirici hata ayıklamayı ayarlayabildiğinden ve rewrite.log dosyalarına erişebildiğinden hata ayıklamak oldukça kolaydır.

  • Paylaşılan bir barındırılan hizmetin kullanıcıları (SHS) .

    • Bu tür kullanıcılar var kullanmak .htaccesshiçbir alternatif olmadığı için / Perdir işleme.
    • Daha da kötüsü, bu tür kullanıcıların beceri düzeyleri (mod_rewrite'ın düzenli ifade kullanan merdiven mantığını kullandıkları sürece) genellikle deneyimli yöneticilerden önemli ölçüde daha düşüktür.
    • Apache ve barındırma sağlayıcıları hata ayıklama / tanılama desteği sunmazlar. Tek teşhis bilgisi başarılı bir yönlendirmedir, yanlış URI'ye bir yönlendirmedir. veya bir 404/500 durum kodu. Bu onları şaşkın ve çaresiz bırakır.
    • Apache, bu kullanım durumu için yeniden yazmanın nasıl çalıştığını açıklayan son derece zayıf. Örneğin, hangi PerDir .htaccessdosyasının seçildiğinin ve nedeninin net bir açıklaması yoktur . PerDir bisikletinin karmaşıklığını ve bunun nasıl önleneceğini açıklamıyor.

Muhtemelen üçüncü bir topluluk vardır: SHS sağlayıcılarında yönetici ve destek personeli, her iki kampta da ayak basacak ve yukarıdakilerin sonuçlarına katlanmak zorunda kalacak.

Birkaç yazı tarzı blog yazısı yazdım (örn . .Htaccess dosyalarında yeniden yazma kuralları hakkında daha fazla bilgi). Bazı özel & VM FLOSS projelerini desteklemenin yanı sıra kendi ortak hizmetim var. SHS hesabım için bir test aracı olarak standart bir LAMP VM kullanmaya başladım, ancak sonunda uygun bir ayna VM yapmayı daha iyi buldum ( burada açıklanmıştır ).

Ancak, yönetici topluluğunun .htaccesskullanıcıları nasıl desteklemesi gerektiği konusunda, geliştirmemiz ve sunmamız gerektiğini düşünüyorum:

  • Yeniden yazma sisteminin gerçekte PerDir işlemede nasıl çalıştığının tutarlı bir açıklaması
  • Yeniden .htaccessyazma kurallarının nasıl yazılacağına dair bir dizi kural / en iyi uygulama
  • W3C html ayrıştırıcılarına benzeyen basit bir web tabanlı yeniden yazma komut dosyası çözümleyici türündedir, ancak kullanıcılar test URI'lerini girebilir veya aynı test vektörlerini girebilir ve yeniden yazma mantığı akışının hemen günlüğünü alabilir.
  • Kurallarınızdan nasıl yerleşik tanı alacağınızla ilgili ipuçları (örn.

    • Hedef betiğe teşhis amaçlı kullanılabilir olmalarını sağlamak için geri referansları ($ N veya% N) genişletecek [E=VAR:EXPR]olan gerçeği değerlendirmek için kullanın EXPR.
    • Yeniden yazma kurallarınızı [VEYA], [C], [SKIP] ve [L] işaretlerini kullanarak topikal olarak düzenlerseniz, tüm yeniden yazma düzeninin dahili yönlendirmeyi kullanmaya gerek kalmadan çalışması için aşağıdakileri kural 1 olarak ekleyebilirsiniz. tüm döngü sorunları:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

Bu iyi belgelenmiştir. Belgelerin bunu açıklamadığını neden söylüyorsun?
adaptr

2
Tek yapmanız gereken .htaccesskonulara abone olmak ve göreceksiniz. Yeni başlayanların çoğu umutsuzca karışıyor - bunların çoğu ilk LAMP hizmeti ve paylaşılan bir hizmet üzerinde mod_rewrite deneyimine sahipler ve bu nedenle sistem / vhost yapılandırmalarına kök erişimi yok ve .htaccessdosyalar arasında işlem yapmak zorunda değiller . Yeni başlayanların "kanaması" gereken önemli farklılıklar var. Kendimi güçlü bir kullanıcı olarak görüyorum ve hala inceliklerini keşfediyorum. Söylediğim gibi, bazı yönleri bulmak için strace ve kaynak kodu taraması kullanmak zorunda kaldım. :-(
TerryE

Tamamen katılıyorum. “Yeniden yazma kullanıcı topluluklarını iki kategoriye ayırmamız ve onları tamamen ayrı olarak ele almamız gerekiyor.” Bazı kullanıcılar hosting kullanan ve ihtiyaç güvenmek .htaccessuzmanların bile, korkunç, kırılgan karmaşık ve kafa karıştırıcı olan. Hala sorun yaşıyorum.
Ryan,

15

Yeniden yazma haritasını kullanma

Yeniden yazma ile yapabileceğiniz birçok şey var. Yeniden Yazma Haritaları, Yeniden Yazma Yönergesi yönergesi kullanılarak bildirilir ve ardından hem RewritCond değerlendirmelerinde hem de RewriteRule Subsitutions'da kullanılabilir.

RewriteMap için genel sözdizimi:

RewriteMap MapName MapType:MapSource

Örneğin:

RewriteMap examplemap txt:/path/to/file/map.txt

Daha sonra böyle yapılar için mapname kullanabilirsiniz:

${examplemap:key}

Harita anahtar / değer çiftleri içeriyor. Anahtar bulunursa, değer değiştirilir. Basit haritalar yalnızca düz metin dosyalarıdır, ancak karma haritaları ve hatta SQL sorgularını kullanabilirsiniz. Daha fazla detay belgelerde:

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Çıkmayan dizeler.

Bazı manipülasyonlar yapmak için kullanabileceğiniz dört dahili harita vardır. Özellikle çıkmaz dizeler kullanışlı olabilir.

Örneğin: Sorgu dizesindeki "café" dizesini test etmek istiyorum. Bununla birlikte, tarayıcı sunucuma göndermeden önce bu durumdan kurtulacaktır, bu nedenle eşleştirmek istediğim her dize için URL'den kaçan sürümün ne olduğunu bulmam gerekecek, ya da sadece unescape ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Sorgu dizesi parametresini değiştirmek için sadece bir RewriteCond kullandığımı ve ardından unescape'i görmek için haritayı ikinci rewriteCond'da kullandığımı not edin. Bu daha sonra karşılaştırılır. Ayrıca, yeniden yazma haritasındaki anahtar olarak% 2'yi nasıl kullanmam gerektiğini,% 1'in "konum" veya "yer" içereceğini de unutmayın. Desenleri gruplandırmak için parantez kullandığınızda, bunlar da yakalanır, yakalamanın sonucunu kullanmayı planlıyor musunuz, yoksa ...


Son cümle tam olarak doğru değil. mod_rewriteRegexp'in motoru gibi olmayan yakalama grupları destekler (?:location|place)ve bu sadece örnek bir yakalama sahip olacaktır.
TerryE

12

Yeniden yazma kurallarını yazarken en sık karşılaşılan hatalar / tuzaklar nelerdir?

Gerçekten kolay bir tuzak, görünen yolu değiştiren URL'leri yeniden yazdığınızda, örn: /base/1234/index.htmlden /base/script.php?id=1234. Komut dosyası konumuna göreceli yolları olan hiçbir resim veya CSS müşteri tarafından bulunmayacaktır. Bu sorunu çözmek için bir dizi seçenek bu SSS'de bulunabilir .


1
Bağlantı için teşekkürler. Özellikle, yeniden yazmaya aşina olmayan diğer ekip üyeleriyle çalışırken, <base>izlemesi en kolay olan ve göreceli yolları etkinleştiren bir etiket eklemeyi düşünüyorum.
kontur
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.