سال 2009 کتاب The Definitive Guide to Apache mod_rewrite را مطالعه کرده بودم و خلاصهای از نکات آن را یادداشت کرده بودم که با توجه به پرسش برخی دوستان در مورد تنظیم mod_rewrite, RewriteRule, RewriteCond, RewriteMap مناسب دیدم اینجا به آن اشارهای بکنم.کاربرد mod_rewrite در تغییر مسیر
یکی از سادهترین کاربردهای mod_rewrite استفاده از آن برای Redirect است. مثلا اگر بخواهید آدرس /a/b.html به آدرس /c/d.php تغییر مسیر یابد، کافی است در فایل htaccess اینطور بنویسیم:Redirect /a/b.html /c/d.php
یا حتی میتوان یک آدرس را به دامنهای دیگر ارجاع داد:Redirect /pics/ http://www.example.com/images/
RedirectMatch همین کار Redirect را انجام میدهد منتها کمی پیشرفتهتر!
و با کمک آن میتوان از عبارات باقاعده برای تغییر مسیر استفاده کرد. مثلا اگر بخواهیم هر آدرس تصویری که در دامنه فعلی است، به آدرس تصویری با همین نام در دامنهای دیگر منتقل شود، میتوان اینگونه نوشت:RedirectMatch (.*).jpg http://images.example.com$1.jpg
فعال کردن ماژول mod_rewrite
برای فعال کردن این ماژول در فایل httpd.conf کافیست خط زیر اضافه شود:LoadModule rewrite_module modules/mod_rewrite.so
یا میتوان در htaccess عبارت:<IfDefine ReverseProxy>
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/libproxy.so
</IfDefine>
و همچنین:RewriteEngine On
را اضافه کرد.
همچنین با کمک کد زیر میتوان log مربوط به ریرایت را فعال کرد تا همه موارد آن ثبت شود:RewriteLogLevel 9
RewriteLog /home/alireza/log/rewrite.log
RewriteLogLevel میتواند روی عددی بین 0 تا 9 ست شود. 0 به معنای لاگ نکردن و 9 به معنای لاگ کردن تمام ریرایتها با جزئیات کامل است که بیشتر برای خطایابی کاربرد دارد.
دقت کنید که کد فوق را حتما باید به httpd.conf اضافه کرد و نه htaccess در غیر اینصورت شما با پیغام خطای RewriteLog not allowed here مواجه میشوید.کار با RewriteRule Directive
ساختار این دستور به صورت زیر است:RewriteRule pattern target_url [flag,flag,flag,…]
عبارت pattern در ساختار RewriteRule با REQUEST_URI تطبیق داده میشود نه کل آدرس. همچنین بر Query String هم تطبیق نمیشود و برای چک کردن پارامترهای ارسالی در آدرس، لازم است ازRewriteCond %{QUERY_STRING} قبل از RewriteRule استفاده کنید.
پرچم (flag) ها زیاد هستند که در ادامه به چندتای آنها اشاره شده. دقت کنید که این پرچمها فقط با کاما باید جدا شوند نه چیز دیگری حتی بدون فاصله (space) اضافه.
پرچم CO یا cookie برای ست کردن کوکی در یک عملیات ریرایت است. ساختار استفاده از این پرچم و یک مثال آن را در ادامه میبینید:cookie|CO=Name:Value:Domain[:Lifetime[:Path]]
RewriteRule ^/index.html - [CO=frontdoor:yes:.example.com]
پرچم E یا env اجاره ست کردن یک متغیر environment را به شما میدهد...
پرچم F کد وضعیت http 403 یا همان Forbidden را به براوزر کاربر میفرستد.
پرچم G کد وضعیت اففح 410 یا همان Gone را به براوزر کاربر میفرستد و براوزر متوجه میشود که آدرس موردنظر دیگر وجود ندارد.
پرچم H که از آپاچی 2.2 به بعد اضافه شده، موجب میشود که آدرس مورد نظر توسط content-handler معین تحلیل شود.
پرچم L که حرف اول Last است، پایان ریرایت و اعمال آن معین میکند.
پرچم N را بایدبه دقت به کار ببرید. این پرچم که از کلمه Next گرفته شده، RewriteRule را آنقدر تکرار میکند تا دیگر pattern بر url تطبیق نشود. فرض کنید شما میخواهید همه خطتیره (dash) های url را به خطزیر (under score) تبدیل شود. در این صورت میتوانید اینطور بنویسید:RewriteRule (.*)-(.*) $1_$2 [N]
حال مثلا اگر آدرس شما به صورت /ali/reza-hasan-kazem.html5 باشد، آنگاه پرچم N در کد فوق موجب میشود که عملیات ریرایت 3 بار (تا اتمام تمام dash ها) تکرار شود.
پرچم NC یا No Case sensitive برای عدم حساسیت pattern به حروف بزرگ و کوچک است.
پرچم NE یا No Escape برای Escape نشدن کاراکترهای target URL است. چون به صورت پیشفرض برخی کاراکترها مثل % و # و ... هنگام ظاهر شدن در URL به %25 و %23 تبدیل میشود در حالی که ممکن است مطلوب ما نباشد.
پرچم QSA یا Query String Append برای اضافه کردن رشته کوئری به URi یی است که قرار است pattern به آن تطبیق شود. (توضیح بیشتر به همراه مثال)
پرچم R برای ارسال کد http 302 به براوزر کاربر است تا براوزر بداند که تغییر مسیر و ریرایت و ریدایرکت فعلی موقت است نه همیشگی.کار با RewriteCond Directive
RewriteCond قبل از RewriteRule نوشته میشود و مانند یک «پیش شرط» برای اجرای آن است. ساختار این دستور به صورت زیر است:RewriteCond TestString Pattern [Flags]
عبارات -d و -f و -s و -l چهار pattern ویژهای هستند که دارای این معانی هستند:
-dچک میکند که آیا TestString به عنوان یک پوشه وجود دارد یا خیر؟
-fچک میکند که آیا TestString به عنوان یک فایل وجود دارد یا خیر؟
-sچک میکند که آیا TestString به عنوان یک فایل دارای حجم بیش از 0 بایت وجود دارد یا خیر؟
-lچک میکند که آیا TestString به عنوان یک symboli link وجود دارد یا خیر؟
همه موارد فوق میتواند با یک علامت ! منفی شود.یک تفاوت در مورد capture کردن کاراکترها با RewriteRule و RewriteCond
زمانی که از پرانتز در عبارات با قاعده برای گرفتن یک گروه از کاراکترها استفاده میکنیم، اگر ازRewriteRule استفاده کرده باشیم، لازم است قبل از شماره گروه پرانتزی کپچر شده، از علامت $ استفاده شود اما در مورد RewriteCond علامت % استفاده میشود.کار با RewriteMap Directive
این مورد که فقط در موارد بسیار تخصصی کاربرد دارد، برای استفاده از منبع خارجی (فایل متنی، دیتابیس، یک برنامه) جهت هدایت ریرایت است...برای توضیحات بیشتر و مثالهای متنوعتر درباره هر یک از موارد فوق، به کتابی که در ابتدای همین مطلب معرفی شد، مراجعه بفرمایید.
لینکهای زیر نیز در این زمینه مفید هستند: