چهارشنبه ۰۹ اسفند ۱۴۰۲

Wednesday, February 28, 2024 GMT +3:30
دسته بندی
×

دوباره نویسی آدرس های وب (URL Rewrite) در htaccess

web-url-rewrite

دوباره نویسی آدرس های وب یا URL Rewrite تکنیکی است که در دانش سئو (علم بهینه سازی برای موتورهای جستجو یا Search Engine Optimization) توصیه شده و امروزه در گستره شبکه جهانی اینترنت مورد استفاده قرار می گیرد، اغلب آدرس های وب به دلیل اینکه به صورت داینامیک ایجاد و به ردیف های پایگاه داده اشاره دارند پارامترها و مقادیر مربوط به ساختار برنامه نویسی و پرس و جوها را در خود نمایش می دهند، به طور مثال در بیشتر سیستم های مدیریت محتوایی که به زبان PHP یا ASP.NET نوشته می شوند برای تنظیم پارامترهای آدرس های URL باید از علامت ?، = و & استفاده شود که این حالت ضمن اینکه ساختار برنامه نویسی سایت را در معرض دید عموم قرار می دهد از نظر سئو و موتورهای جستجو نیز بهینه نیست، البته اینکه واقعا آدرس های داینامیک در مقابل آدرس های استاتیک (URL هایی که پارامتر متغیر ندارند و همواره ثابت هستند) تا چه میزان روی عملکرد صفحات وب از نظر سئو تاثیر گذار است خود جای بحث دارد، اما به دلایل دیگر شاید هنوز ضرورت استفاده از آدرس های استاتیک برای داشتن صفحات وب بهینه همچنان احساس شود، به هر صورت به جهت کاربردی بودن این تکنیک مطلب پیش رو را به آموزش نحوه دوباره نویسی آدرس های وب (URL Rewrite) در فایل htaccess اختصاص داده ایم.

ضرورت استفاده از آدرس های استاتیک


ممکن است این سوال در ذهن خیلی از برنامه نویسان و مدیران سایت های وب وجود داشته باشد که آیا حتما باید از آدرس های URL استاتیک استفاده کنیم؟
پاسخ به این پرسش بستگی زیادی به هدف و میزان تسلط و آشنایی ما با برنامه مدیریت محتوایی دارد که از آن برای سایت خود استفاده می کنیم (برنامه های مدیریت محتوا تحت عنوان CMS یا Content Management System شناخته می شوند)، دلایلی برای استفاده از آدرس های استاتیک ارائه می شود از جمله اینکه:
- حفظ امنیت و مخفی سازی ساختار برنامه نویسی
- کوتاهتر بودن URL و سهولت به حافظه سپاری
- کسب رتبه بهتر در موتورهای جستجو و کلیک بیشتر
به لحاظ حفظ امنیت و مخفی سازی ساختار برنامه نویسی CMS ها این گونه آدرس ها از ضریب اطمینان بالاتری برخوردارند، چرا که URL های داینامیک معمولا ساختار مشخص و در معرض دیدی دارند که نحوه قرارگیری دایرکتوری ها و عناوین واقعی ستون های دیتابیس را نمایان می کند اما با دوباره نویسی آدرس ها ساختار URL ها به نحو دلخواه پیچیده و نامفهوم می شود، مثال:
example.com/index.php?id=1&title=url-rewrite

example.com/1/url-rewrite
در این مثال پسوند php به راحتی زبان برنامه نویسی سایت را مشخص می کند و پارامترهای id و title احتمالا اشاره مستقیم به نام ستون های پایگاه داده دارند که در کل به لحاظ امنیت توصیه نمی شود، هرچند وجود پارامترها یا مشخص بودن زبان برنامه نویسی سایت به خودی خود مشکلی ایجاد نمی کند و به صرف این حالت امکان نفوذ به برنامه ما وجود ندارد اما در مقوله امنیت اصل کلی این است که کمترین اطلاعات از تکنولوژی به کار رفته نمایان باشد و پیچیده ترین ساختار را داشته باشیم.
دلیل دیگر توصیه به استفاده از این شیوه کوتاه و خواناتر شدن آدرس های URL و حذف علامت های ?، = و & از آن است، آدرس های استاتیک معمولا کوتاهترند و این در سئو یک مزیت محسوب می شود، البته این گفته بستگی زیادی به تعداد کاراکتر استفاده شده در آدرس URL دارد (هر چه کوتاهتر، بهتر)، آدرس های کوتاهتر و فاقد علامت های داینامیک با سهولت بیشتری به خاطر سپرده می شوند.
مزیت بعدی که در خصوص آدرس های بازنویسی شده گفته می شوند اینکه در لیست نتایج موتورهای جستجو معمولا آمار کلیک بهتری کسب می کنند و به اصطلاح کلیک خور بهتری دارند، دلیل این موضوع هم علاقه گوگل به این سبک آدرس ها و خواناتر بودن آنها به دلیل کوتاهی و وجود عبارات کلیدی در آدرس URL است، البته باید توجه کرد بین یک آدرس داینامیک با پارامترهای مناسب و کوتاه و آدرس استاتیک با شرایط مشابه از نظر کسب کلیک بیشتر شاید آنچنان فرق محسوسی ملموس نباشد.

تصورات اشتباه در خصوص آدرس های وب


هرچند دانش سئو بر ضرورت استفاده از آدرس های دوباره نویسی شده در وب تاکید دارد اما تصورات اشتباهی نیز در این خصوص شکل گرفته است، بعضا گفته می شود که موتورهای جستجو قادر به ایندکس صفحات ارجاعی از آدرس های داینامیک نیستند که این تصور کاملا اشتباه است، تمام موتورهای جستجوی معروف به خوبی آدرس های داینامیک را درک و محتوای آنها را ایندکس می کنند منتها URL های استاتیک به دلایلی که در بالا اشاره شد توصیه می شوند، تصور اشتباه دیگر اینکه می گویند آدرس بازنویسی شده نمی تواند هیچ پارامتر داینامیکی داشته باشد که این گفته نیز کاملا اشتباه است، هدف از دوباره نویسی می تواند بسته به نیاز متفاوت باشد، به فرض ممکن است به لحاظ فنی امکان حذف تمام یا بخشی از پارامترهای داینامیک وجود نداشته باشد (به فرض در موتورهای جستجو شاهد هستیم که این پارامترها همچنان در آدرس URL وجود دارند) و صرفا زبان برنامه نویسی سایت را مخفی می کنند، مثال:
example.com/index.php?id=1&title=url-rewrite

example.com/?id=1&title=url-rewrite
در این مثال صرفا قسمت index.php حذف شده است و به خودی خود اشکالی ایجاد نمی کند (هرچند در سئو هر چه آدرس URL پارامتر داینامیک کمتری داشته باشد بهتر است).

کدام شکل URL را انتخاب کنیم؟


همانطور که گفتیم این امر بستگی زیادی به هدفمان دارد، به فرض اگر نوع فعالیتمان در وب طوری است که رقابت تنگاتنگ با سایرین از لحاظ جذب بازدیدکننده اهمیت زیادی برایمان دارد و سایر اصول مربوط به بهینه سازی را نیز رعایت کرده ایم، توصیه می شود این مورد را هم فرا گرفته و در کنار دیگر اصول وب و مسائل فنی از آن استفاده کنیم، اما اگر به طور مثال سایتی اداری یا شخصی را مدیریت می کنیم و جوانب امنیتی پایگاه داده را هم رعایت کرده ایم دوباره نویسی آدرس ها چندان ضرورتی نخواهد داشت، کما اینکه بسیاری از سایت های موفق هستند که از لینک های داینامیک استفاده می کنند و مشکل خاصی نیز برای آنها از این لحاظ پیش نمی آید، از طرفی برای برخی برنامه های وب به دلیل تعداد زیاد پارامترها عملا امکان دوباره نویسی وجود ندارد به طور مثال موتورهای جستجو، سایت های خرید آنلاین و... بنابراین همه چیز بستگی به خودمان و نوع کار دارد.

نکات مهم دوباره نویسی آدرس های وب (URL Rewrite)


باید یادآور شویم دوباره نویسی آدرس های داینامیک وب (URL Rewrite) کار حساسی است و باید با دقت و تسلط کامل انجام شود، اشتباه در این مورد ممکن است باعث بروز مشکلاتی از جمله ایجاد محتوای تکراری (Duplicate Content) و یا اختلال در عملکرد سایت شود، البته در صورت گرفتن پشتیبان از دستورات موجود خوشبختانه تغییرات فایل htaccess به سرعت قابل بازگشت به حالت سابق است چون سرور در هر بار فراخوانی آدرس های URL، کدهای htaccess را مجددا اجرا کرده و برای نشست جاری آخرین دستورات را اعمال می کند اما با این وجود بازنویسی باید با در نظر گرفتن تمام احتمالات و آزمایش های لازم قبلی صورت گیرد تا جایی برای هیچگونه اشتباه ناخواسته باقی نماند، بعضا شاهد هستیم که یک قانون به خودی خود مشکلی ایجاد نکرده اما به جهت تداخل با سایر قوانین در نهایت موجب بروز اشکالاتی در عملکرد سایت یا برنامه های تحت وب شده است، اکثر این موارد در صورت تست و آزمایش و خطای قبلی قابل شناسایی و رفع هستند.

آشنایی با mod_rewrite در سرورهای Apache


دوباره نویسی یا Rewrite آدرس ها در سرورهای لینوکسی Apache با کمک ماژولی به نام mod_rewrite انجام می شود، این ماژول تقریبا یکی از محبوب ترین، قدرتمند ترین و پرکاربردی ترین ها در این نوع سرورها است و قدرت آن در حدی است که هر نوع دستکاری در ساختار لینک های سایت توسط mod_rewrite میسر می شود، اصول کار این ماژول بر اساس عبارات با قاعده یا Regular Expressions است که قوانین خاصی برای آن با این روش تعریف می شود که به آنها Rewrite Rule می گویند، اگرچه گستره قواعد و ویژگی های این ماژول بسیار زیاد است اما برای استفاده های معمول می توان با فراگیری چند تکنیک و دستور ساده نیازهای سرویس یا سایت تحت وب مد نظرمان را برطرف کنیم، این قابلیت در بیشتر سرورهای Apache به صورت پیش فرض فعال است اما اگر در هاستمان فعال نبود می توانیم موضوع را با پشتیبان فنی سرور خود مطرح کنیم، نصب و استفاده از این ماژول بسیار آسان و پرکاربرد است و معمولا پشتیبان فنی هاست آن را هنگام اعمال تنظیمات سرور فعال می کند.

URL Rewrite در سرورهای ویندوز


در سرورهای ویندوز ماژول mod_rewrite وجود ندارد اما با پلاگین های جایگزین دیگری می توانیم عملیات دوباره نویسی آدرس ها را با سرورهای لینوکس شبیه سازی کنیم، به طور مثال پلاگینی با نام ISAPI_Rewrite در سرورهای ویندوز می تواند رهگشا باشد.

نحوه دوباره نویسی آدرس های وب


برای دوباره نویسی آدرس های وب قبل از هر چیز به فایل متنی ساده بدون نام و با پسوند htaccess. در ریشه سایتمان (پوشه www یا public_html) نیاز خواهیم داشت، اگر فایل htaccess. به طور پیش فرض در سرور وجود ندارد می توانیم به راحتی آن را در برنامه مدیریت هاست مانند cPanel یا DirectAdmin ایجاد کنیم، با توجه به بی نام بودن این فایل در محیط ویندوز ساخت آن ممکن است به سادگی ممکن نباشد که با راه حل زیر می توانیم این مشکل را رفع کنیم:
برنامه Notepad را اجرا کرده و در صورت نیاز دستورات مورد نظرمان را درون آن درج می کنیم، سپس از گزینه File قسمت Save As را انتخاب کرده و زبانه Save as type را بر روی All files تنظیم می کنیم، نهایتا در قسمت File name عبارت htaccess. را تایپ و فایل را ذخیره می کنیم (دقت کنیم در هنگام تایپ نام فایل نقطه باید در ابتدا باشد!)، راه حل جایگزین اجرای برنامه Command Prompt ویندوز و درج دستور زیر در آن است:
copy con .htaccess
سپس دو بار دکمه Enter را بزنید، فایل در آدرس مورد نظر (معمولا دایرکتوری مربوط به User ویندوز) ایجاد می شود.
دقت کنیم که نقل و انتقال این فایل از سیستم عامل به سرور مخصوصا از طریق برنامه های پروتکل FTP باید به صورت ASCII انجام شود نه باینری (BINARY)، سپس مطابق نیازمان دستوراتی که در ادامه بررسی خواهیم کرد را در آن درج و تنظیم می کنیم.
شیوه نگارش (Syntax) کلی دستورات htaccess به شکل زیر است:
RewriteRule Pattern Target/Substitution [Flags] 
فرض کنیم آدرس زیر را می خواهیم دوباره نویسی کنیم:
http://example.com/index.php?q=home
هدف ما این است که آدرس بالا را به صورت زیر بازنویسی کنیم، یعنی با وارد کردن آدرس زیر در مرورگر سرور پارامترهای URL بالا را در پس زمینه دریافت کند:
http://example.com/home
بدین منظور ابتدا ماژول mod_rewrite را روشن می کنیم، سپس از قوانین آن استفاده کرده و با عبارات با قاعده (در ادامه در این خصوص بیشتر خواهیم گفت) یک قانون (Rewrite Rule) می نویسیم تا وقتی سرور آدرس درخواستی را با آن مطابقت داد قانون ما عمل کرده و پارامترهای اصلی در پس زمینه دریافت شوند:
RewriteEngine On
RewriteRule ^home /index.php?q=home [NC,L]
با کپی عبارت بالا در فایل htaccess. و قرار دادن آن در ریشه سایت، سرور آدرس دریافتی را با قسمت Pattern بررسی و اگر با الگوی قانون تعریف شده مطابقت داشته باشد آدرس اصلی (قسمت Target/Substitution - هدف/جایگزین) را بازنویسی می کند، در واقع پارامتر اول در قسمت الگو (home) منطبق بر ساختار URL استفاده شده در سایت و قسمت دوم قانون (index.php?q=home) همان آدرس نهایی بازنویسی شده برای استفاده در سرور و برنامه PHP است، به عبارتی قانون بالا از دو قسمت تشکیل شده است، در بخش اول آدرس درخواست شده از سرور بررسی می شود، اگر این آدرس با الگوی (Pattern) ما که در RewriteRule در نظر گرفته ایم مطابقت داشت آدرس استاتیک درخواستی به صورت پارامترهای داینامیک قسمت دوم هدف (Target) جانشین (Substitution) می شود، یعنی اگر در قسمت ابتدایی آدرس استاتیک بعد از دامنه سایت عبارت home وجود داشته باشد سرور آدرس را به صورت index.php?q=home شناسایی می کند، علامت هایی مانند ^ که در قانون نویسی به کار می روند معنی خاصی دارند که به آنها دستورات عبارات با قاعده یا Regular Expressions گفته می شود، حروف [NC,L] نیز معنی خاصی در زمینه نحوه پردازش قوانین دارند و با این روش منظورمان را به سرور تفهیم می کنیم، به طور مثال NC (nocase) به معنی Not Case-sensitive یا حساس نبودن به حروف بزرگ و کوچک است، یا حرف L به معنی Last و آخرین دستور است یعنی اگر این قانون اجرا شد بقیه قوانین بعد از آن نادیده گرفته می شوند، به این حروف نشانه گذاری در اصطلاح پرچم ها یا Flags می گویند، در ادامه دستورات باقاعده (Regular Expressions) و پرچم ها (Flags) در htaccess را بررسی می کنیم.
نکته: اگر قوانین را درست و کامل ننویسیم معمولا خطای داخلی سرور با کد 500 یا همان HTTP Error 500 Internal Server Error دریافت خواهیم کرد.

عبارات با قاعده (Regular Expressions) در htaccess


برای نوشتن و کاربرد صحیح قوانین دوباره نویسی باید حداقل آشنایی مختصری با عبارات با قاعده (Regular Expressions) داشته باشیم، عبارات باقاعده زبانی قراردادی جهت انتخاب یا بررسی قسمت خاصی از یک رشته متنی است، به طور مثال اگر در رشته متنی زیر که یک آدرس URL فرضی است:
http://example.com/find/?search=htaccess&page=23
بخواهیم صرفا اعداد را استخراج کنیم عبارت باقاعده آن می تواند به این شکل نوشته شود:
([0-9]+)
اگر در همین رشته بخواهیم مقادیر پارامتر search را از URL استخراج کنیم عبارت باقاعده آن به شکل زیر خواهد بود:
^search=([^&]*)
هر کاراکتر در RegExp معنی و کاربرد خاص خود را دارد که آموزش مفصل آن در آدرس زیر در دسترس است:
آموزش کاربردی عبارات با قاعده (Regular Expressions)
در ادامه صرفا جهت یادآوری چند نوع کاراکتر دستوری متداول از عبارت باقاعده را همراه با معنی آنها بررسی می کنیم:
Anchors یا لنگرها:
لنگرها شروع و پایان یک رشته را در الگو مشخص می کنند، به فرض الگوی زیر به معنی کلیه آدرس هایی است که بعد از دامنه سایت قسمت دوم آنها با اعداد (0 تا 9) شروع می شود:
^([0-9]+)$
الگوی بالا با URL فرضی زیر تطبیق دارد:
http://www.example.com/143231
علامت ^ ابتدای دامنه دستور را بعد از آدرس دامنه مشخص می کند و به معنی نقطه شروع الگو است، علامت $ انتهای دامنه دستور را مشخص می کند و به معنی نقطه پایان الگو است، با این توضیح قبل از علامت ^ و بعد از علامت $ نباید کاراکترهای متنی دیگری داشته باشیم در این صورت الگو با متن مطابقت نمی کند، به طور مثال الگوی بالا با URL های فرضی زیر تطبیق ندارد:
http://www.example.com/143231/dir

http://www.example.com/dir/143231
دسته بندی ها یا Character Classes:
نوع دیگر از دستورات باقاعده با حروف الفبای انگلیسی مانند w ،s ،W ،d و... (حساس به بزرگ یا کوچک بودن حروف) تعریف می شوند، به فرض کاراکتر d\ با اعداد (0 تا 9) مطابقت دارد، یا حرف w\ به معنی حروف و اعداد انگلیسی است، همچنین W\ شامل همه چیز به جزء حروف و اعداد انگلیسی می شود، کاراکتر s\ (با حروف کوچک) نیز به معنی فضای خالی و S\ به معنی هرچیزی به جز فضای خالی است.
نکته: برای تفهیم دستوری بودن کاراکترها به سیستم از یک بک اسلش (\) قبل از حروف الفبا استفاده می کنیم، جالب است که در برخی موارد (به طور مثال کاراکتر نقطه) این بک اسلش کاراکتر را از حالت دستوری خارج و به یک حرف متنی ساده تبدیل می کند، نقطه در دستورات عبارات باقاعده به معنی "هر کاراکتر" است اما با درج بک اسلش قبل از آن حالت دستوری خنثی می شود.
تاکیدات یا Assertions:
یک نوع دیگر از کاراکترهای دستوری عبارات با قاعده تاکیدات هستند، به اینصورت که اگر به فرض لینک دریافتی را برای وجود حرف a بررسی کرده و در عین حال بخواهیم بعد از حرف a کلمه فرضی book نیز نیامده باشد، خواهیم نوشت:
[^\S]*a(?!book)[^\S]*
قسمت مربوط به حرف S (با حروف بزرگ) و کاراکتر * (تعداد تکرار صفر یا بیشتر) در اینجا به معنی هر چیزی به جزء فاصله خالی در عبارت به تعداد تکرار صفر یا بیشتر است، به عبارتی وجود یا عدم وجود این قسمت اختیاری است، سپس وجود حرف a بررسی می شود و بعد از آن عدم وجود کلمه book و سپس نبودن فضای خالی، اگر آدرس URL درخواستی از این الگو پیروی کند قسمت دوم قانون اجرا می شود.
گروه و حدود:
یکی از پرکاربردترین نوع دستورات در عبارات با قاعده گروه ها و حدود هستند، به فرض اگر بخواهیم قسمت خاصی از یک رشته را انتخاب کنیم می توانیم دستورات را بین کاراکترهای () درج کنیم، مثال:
([\w]+)
این دستور حروف و اعداد انگلیسی را از رشته استخراج می کند، کاراکتر + نشان دهنده الزام به وجود حداقل یک حرف یا عدد است.
نکته: در htaccess می توانیم گروه های داخل () را به صورت شماره گذاری شده دریافت (Capture) کنیم، برای این منظور از کاراکتر $ (علامت دلار یا Dollar Sign) و شماره گروه مورد نظر استفاده می کنیم، مثال:
RewriteRule ([a-z0-9/-]+)-([a-z]+).html$ $1-$2.php [NC,L,QSA]
علاوه بر این اگر بخواهیم بررسی کنیم که در رشته متنی عباراتی خارج از محدوده اعداد 0 تا 9 و حروف a تا z قرار دارد یا خیر، با استفاده از کاراکترهای [] و بدون تعریف گروه خواهیم نوشت:
[^A-Za-z0-9]+
کاراکتر ^ داخل حدود [] حالت منفی می گیرد و به معنی "هر کاراکتری به جز" است.
کاراکتر | به معنی "یا":
کاراکتر دستوری "یا" با علامت | نیز در عبارات با قاعده کاربرد زیادی دارد، به فرض گروه زیر به معنی وجود حروف web یا goo در رشته متنی است:
(web|goo)
کاراکترهای دستوری عبارات با قاعده تنوع زیادی دارند و آموزش تمام آنها با جزئیات در این مطلب ممکن نیست، در اینجا بیشتر آشنایی اولیه با شیوه نگارش و هدف از به کارگیری آنها در نوشتن قوانین دوباره نویسی URL های وب مد نظر است.

پرچم ها (Flags) در htaccess


قسمت آخر در تعریف قوانین دوباره نویسی آدرس های وب استفاده از پرچم ها (Flags) است که به صورت [flag1,flag2,flag3] نوشته می شوند، با پرچم ها می توانیم نحوه پردازش دستورات را در فایل htaccess مدیریت کنیم، پرچم ها در دو شکل کوتاه یا کامل (به فرض L یا last) قابل استفاده هستند اما عمدتا شکل کوتاه آنها به کار می رود، این عبارات دستوری طیف های متنوعی دارند و هر کدام با هدف خاصی به کار می روند که در ادامه چند مورد از مهمترین ها را بررسی می کنیم:
- پرچم END
این پرچم اجرای دستورات htaccess را در نشست جاری به طور کامل متوقف می کند، البته تفاوت آن با L در این است که اگر چند فایل htaccess در دایرکتوری اصلی و دایرکتوری های زیرمجموعه داشته باشیم، با END اجرای تمام این فایل ها متوقف می شود اما با L صرفا فایل حاوی این دستور اجرایش متوقف می شود:
RewriteEngine On
RewriteRule ^index/([0-9]+)$ /index.php?page=$1[NC,END]
- پرچم F یا forbidden
در صورت استفاده از این پرچم و تطبیق الگو با آدرس URL درخواستی، سرور خطای وضعیت Forbidden 403 برمی گرداند:
RewriteRule "\.exe" "-" [F]
این قانون اجرای فایل های با پسوند exe از طریق فراخوانی آدرس URL را در سایت ممنوع می کند.
- پرچم L یا last
با اجرای قانون متناظر با این پرچم، مفسر دیگر قوانین را در فایل جاری نادیده می گیرد:
RewriteRule ^posts/([0-9]+)-(.*)\.html$ posts.php?id=$1 [NC,L]
تفاوت پرچم L با END در این است که با اجرای پرچم END تمام قوانین چه در فایل فعلی و چه در دیگر فایل هایی که ممکن است در دایرکتوری های زیرمجموعه ریشه سایت وجود داشته باشند خاتمه می یابند اما پرچم L صرفا اجرای ادامه قوانین را در فایل htaccess جاری متوقف می کند.
- پرچم NC یا nocase
در صورت درج این پرچم بزرگ یا کوچک بودن حروف اهمیتی ندارد و الگوی قانون در هر دو حالت تطبیق پیدا می کند:
RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [NC]
در این مثال بزرگ یا کوچک بودن فرمت فایل ها مهم نیست و در صورت تطبیق با الگو قسمت دوم قانون برای سرور دریافت می شود.
- پرچم QSA یا qsappend
اگر آدرس درخواستی از سرور یک یا چند پارامتر داینامیک داشته باشد، به فرض:
http://example.com/news/123/?cat=2&title=this-is-easy
در حالت عادی پارامترهای داینامیک در قانون دوباره نویسی دخیل نمی شوند و قابل بررسی هم نیستند، به طور مثال اگر قانون زیر را داشته باشیم و کاربر آدرس بالا را از سرور درخواست کند:
RewriteRule ^news/(.*)$ news.php?url=$1 [NC,L]
در نهایت آدرس زیر برای استفاده در سرور دریافت می شود:
news.php?url=123
اما اگر قانون را با افزودن پرچم QSA به شکل زیر تغییر دهیم:
RewriteRule ^news/(.*)$ news.php?url=$1 [QSA,NC,L]
آدرس نهایی برای سرور به این صورت خواهد بود:
news.php?url=123/?cat=2&title=this-is-easy
- پرچم R یا redirect
برای انتقال کاربر از آدرس فعلی به آدرس مد نظرمان از پرچم R یا عبارت redirect استفاده می کنیم، این انتقال می تواند به همراه تنظیم کدهای وضعیت سری 300 الی 399 باشد، به طور مثال قانون زیر آدرس درخواستی را به صورت همیشگی (Permanently) به URL جدید منتقل می کند:
RewriteRule ^old-([0-9]+)$ new-$1 [R=301,NC,L]
برای تنظیم عدد متناظر با وضعیت HTTP از علامت = در مقابل R استفاده می کنیم.
نکته: پرچم R باید به همراه پرچم L استفاده شود، فلسفه این کار مشخص است، با ریدایرکت در واقع قصد اتمام بارگذاری آدرس درخواستی جاری و انتقال به آدرس جدید را داریم و لذا پردازش ادامه قوانین در نظر گرفته شده برای URL فعلی منطقی نیست و ممکن است با خطاهای ناخواسته مواجه شویم.
تعداد پرچم های قابل استفاده در هنگام نوشتن قوانین دوباره نویسی به موارد گفته شده ختم نمی شود، برای آشنایی بیشتر می توانیم به لینک زیر رجوع کنیم:
https://httpd.apache.org/docs/2.4/rewrite/flags.html

تعیین شرط و پارامترهای آن در دستورات htaccess


یکی از قابلیت های کاربردی که ماژول mod_rewrite در اختیارمان قرار می دهد امکان تعیین شرط یا Rewrite Conditions با شیوه نگارش (Syntax) زیر است:
RewriteCond TestString CondPattern [Flags]
اما تعیین شرط چه کاربردی دارد؟
در هنگام نوشتن قوانین دوباره نویسی مواردی پیش می آید که بخواهیم اجرای یک قانون را منوط به وجود شرایطی کنیم، یعنی ابتدا بررسی کنیم اگر شرایط مد نظرمان محقق شده بود قانون بعد از آن اجرا شود، مثال:
RewriteCond "%{QUERY_STRING}" "hack" [NC]
RewriteRule "." "-" [F]
این دستور تمام آدرس هایی که قسمت بعد از علامت ? (Query String) در آنها شامل کلمه hack باشد را مسدود (403 Forbidden) می کند.
تعداد شروط برای یک قانون می تواند بیش از یک مورد باشد، به طور مثال اگر بخواهیم یک استثنا برای قانون بالا تعریف کنیم که به فرض اگر کوکی شامل عبارت debug از مرورگر دریافت نشد قانون اجرا شود، خواهیم نوشت:
RewriteCond "%{QUERY_STRING}" "hack" [NC]
RewriteCond %{HTTP_COOKIE} !debug [NC]
RewriteRule "." "-" [F]
هر دو شرط بالا باید برقرار باشند تا قانون اجرا شود، در واقع به صورت پیش فرض برای دو شرط پرچم AND استفاده می شود اگر نیاز است که صرفا با برقراری یک شرط قانون اجرا شود می توانیم از پرچم OR (ornext) استفاده کنیم:
RewriteCond "%{QUERY_STRING}" "hack" [NC,OR]
RewriteCond %{HTTP_COOKIE} !debug [NC]
RewriteRule "." "-" [F]
پرچم OR صرفا در قسمت شرط ها قابل استفاده است نه در قسمت قوانین که این به فلسفه تعریف این پرچم بر می گردد.
همان طور که در نمونه دستورات بالا مشخص است در قسمت اول هر شرط پارامترهایی به شکل 
 %{NAME_OF_VARIABLE}
مشاهده می شود که به آنها متغیرهای سرور می گوییم، این متغیرها بسته به مورد می توانند شامل اطلاعات مختلفی از مرورگر کاربر و امکانات سرور باشند که اسامی آنها در جدول زیر آمده است:
HTTP HeadersConnection & RequestServer Internals
HTTP_ACCEPT
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_REFERER
HTTP_USER_AGENT
AUTH_TYPE
CONN_REMOTE_ADDR
CONTEXT_PREFIX
CONTEXT_DOCUMENT_ROOT
IPV6
PATH_INFO
QUERY_STRING
REMOTE_ADDR
REMOTE_HOST
REMOTE_IDENT
REMOTE_PORT
REMOTE_USER
REQUEST_METHOD
SCRIPT_FILENAME
DOCUMENT_ROOT
SCRIPT_GROUP
SCRIPT_USER
SERVER_ADDR
SERVER_ADMIN
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
Date & TimeSpecials
TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
API_VERSION
CONN_REMOTE_ADDR
HTTPS
IS_SUBREQ
REMOTE_ADDR
REQUEST_FILENAME
REQUEST_SCHEME
REQUEST_URI
THE_REQUEST
نکته: گروه هایی که در قسمت Rewrite Rule تعریف می کنیم با کاراکتر $ (دلار - Dollar) و عدد متناظر گروه قابل دریافت هستند، اما گروه های به کار رفته در قسمت Rewrite Conditions را با کاراکتر % (درصد - Percent) می توانیم در قانون خود داشته باشیم، به طور مثال:
RewriteCond "%{DOCUMENT_ROOT}" !-f
RewriteCond %{HTTP_HOST} ^(sub.example.com)$
RewriteRule ^/?([a-z]+)/([0-9]+)$ /panel.php?action=$1&page=$2&host=%1
به نظر این کاراکترها ($، %) بخشی از قوانین قراردادی در شیوه نگارش (Syntax) دستورات htaccess هستند و احتمالا فلسفه قابل ذکر دیگری ندارند.
در قسمت دوم RewriteCond بسته به هدف از نوشتن شرط موارد زیر به عنوان CondPattern قابل استفاده است:
- بررسی منفی (برابر نبودن) با علامت !، مثال:
RewriteCond %{REQUEST_FILENAME} !-d
این شرط بررسی می کند که نام فایل درخواستی با یک دایرکتوری در سرور برابر نباشد.
- مقایسه با علامت های <=> برای مقادیر رشته ای یا عدد، مثال:
RewriteCond %{HTTP_USER_AGENT} "=This Browser/Ver 28.0"
این مقایسه برابر بودن متغیر سرور HTTP_USER_AGENT که معمولا حاوی اطلاعاتی از مرورگر کاربر است را با رشته متنی در نظر گرفته شده در دابل کوتیشن بررسی می کند.
- مقایسه با حروف دستوری خاص برای مقادیر رشته ای یا عدد، مثال:
RewriteCond %{HTTP_HOST} eq "example.com"
این حروف شامل:
eq مشتق از واژه equal to یا برابر با.
ge مشتق از سرواژه های greater than  و equal to به معنی بزرگتر از یا برابر با.
gt مشتق از سرواژه های greater than به معنی بزرگتر از.
le مشتق از سرواژه های less than و equal to به معنی کوچکتر از یا برابر با.
lt مشتق از سرواژه های less than به معنی کوچکتر از.
ne مشتق از سرواژه های not equal to به معنی برابر نبودن با (حالت حروفی کاراکتر دستوری !).
- بررسی صفت های مربوط به فایل و دایرکتوری، مثال:
RewriteCond /old/page/%{REQUEST_URI} !-f
RewriteRule ^(.+) /other/archive/$1 [R=301]
در ادامه برخی از پر کاربردترین کاراکترهای مربوط به بررسی فایل و دایرکتوری در htaccess را بررسی می کنیم:
d مشتق از سرواژه directory جهت بررسی وضعیت وجود و دایرکتوری بودن (یا در حالت منفی نبودن) آدرس.
f مشتق از سرواژه file جهت بررسی وضعیت وجود و فایل بودن (یا در حالت منفی نبودن) آدرس.
l مشتق از سرواژه link جهت بررسی وضعیت نمایشی (symbolic) بودن یا نبودن آدرس، لینک های سمبلیک یا نمایشی آدرس های URL ای هستند که منبع واقعی برای آنها در سرور وجود ندارد (به فایل خاصی اشاره نمی کنند) و صرفا جنبه نمایشی دارند، معمولا این سبک آدرس ها با دوباره نویسی برای سرور قابل فهم می شوند.
- استفاده از دستورات باقاعده (Regular Expressions)، مثال:
RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
RewriteRule "^/images" "-" [F]
دستور بالا در شرط آدرس ارجاعی (Referer) را با هاست (Host) بررسی می کند، برای استفاده از دستورات باقاعده (Regular Expressions) لازم است که قسمت expr و strmatch مطابق با نمونه بالا در دستور وجود داشته باشد.

چند مثال کاربردی دوباره نویسی آدرس های وب (URL Rewrite)


جزئیات امکانات htaccess برای دوباره نویسی آدرس های وب به مواردی که بررسی کردیم ختم نمی شود، البته یادگیری تمام مباحث نه لازم است و نه مقدور، به هر صورت در نهایت هدف از طرح مباحث این است که بتوانیم نیازه های متنوع وبسایت ها و برنامه های تحت وب را در زمینه های مختلف پوشش دهیم، در ادامه با چند مثال کاربردی در خصوص نحوه استفاده کاربردی از دستورات htaccess در دوباره نویسی آدرس های وب (URL Rewrite) آموزش را به پایان می بریم.

انتقال آدرس از index.html به index.php


در این مثال آدرس صفحه اصلی را از index.html به index.php دوباره نویسی می کنیم:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html
RewriteRule ^index\.html$ http://example.com/index.php [R=301,L]
تفسیر دستور بالا:
اگر مقدار بازگشتی از متغیر سرور THE_REQUEST با حروف بزرگ انگلیسی به تعداد حداقل 3 و حداکثر 9 کاراکتر شروع و در این مقدار عبارت index.html نیز وجود داشت قانون بعدی اجرا شده و در صورتی که آدرس URL درخواستی با الگوی قانون مطابقت کند با پرچم R=301 که به معنی ریدایرکت همیشگی (Moved Permanently) است، کاربر از حالت index.html به آدرس http://example.com/index.php منتقل می شود.
نکته: متغیر THE_REQUEST شامل نمونه اطلاعات زیر است:
"GET /index.html HTTP/1.1"
انتقال از index.html به index.php را می توانیم بدون شرط نیز بنویسیم:
RewriteEngine on
RewriteRule ^index\.htm$ index.php [NC,R=301]

دوباره نویسی آدرس داینامیک با یک پارامتر متنی


در این مثال آدرس داینامیک با یک متغیر متنی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([^/]+) /?category=$1 [NC,L]
به فرض آدرس نمایشی http//example.com/category/learn در سرور به صورت http//example.com/?category=learn دریافت می شود، همانطور که گفتیم گروه های تعریف شده بین کاراکترهای () در قسمت RewriteRule با علامت $ و شماره متناظر آن مشخص می شوند، در این نمونه دستور نیز عبارت learn به این شیوه برای سرور بازنویسی شده است.

دوباره نویسی آدرس داینامیک با یک پارامتر عددی


در این مثال آدرس داینامیک با یک متغیر عددی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([0-9]+) /?category=$1 [NC,L]
به فرض آدرس نمایشی http//example.com/category/5 به صورت http//example.com/?category=5 دریافت می شود.

دوباره نویسی آدرس داینامیک با دو پارامتر متنی و عددی


در این مثال آدرس داینامیک با دو پارامتر متنی و عددی را دوباره نویسی می کنیم:
RewriteEngine On
RewriteRule ^category/([0-9]+)/([^/]+) /?category=$1&title=$2 [NC,L]
دستور بالا آدرس نمایشی http//example.com/category/5/learn-web را به صورت http//example.com/?category=5&title=learn-web دوباره نویسی خواهد کرد.

انتقال از آدرس بدون www به آدرس با www و برعکس


در مثال زیر دستوری تنظیم کرده ایم که اگر در آدرس درخواستی ورودی عبارت www تایپ نشده بود کاربر به آدرس با www هدایت شود:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com$ [NC]
RewriteRule .? http://www.example.com%{REQUEST_URI} [R=301,L]
برعکس این حالت یعنی انتقال از آدرس با www به آدرس بدون www (به اصطلاح non-www) را نیز با دستور زیر می توانیم تعریف کنیم:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
متغیر سرور HTTP_HOST معمولا شامل آدرس اصلی سایت است که از مرورگر دریافت می شود، به طور مثال example.com و REQUEST_URI قسمت بعد از آدرس سایت را شامل می شود.

دانلود غیر مستقیم فایل های PDF


یکی از کاربردهای جالب دوباره نویسی آدرس های وب در htaccess امکان ایجاد قابلیت دانلود غیر مستقیم فایل ها و پردازش ابتدایی آنها با دستورات PHP به فرض جهت بررسی مجاز بودن دسترسی کاربر است، به طور مثال:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.+)\.pdf$  /include/pdf.php?file=$1 [L,NC,QSA]
در این مثال در صورتی که کاربر فایلی با پسوند pdf را از سرور درخواست کند قبل از بارگذاری فایل در مرورگر (روند عادی) ابتدا در فایل pdf.php دریافت و پردازش مورد نظر اعمال می شود، به فرض اگر کاربر وارد سایت شده و مجاز به دانلود بود در نهایت با دستورات PHP فایل جهت دانلود به سمت مرورگر ارسال می شود.

حذف index.php از آدرس URL


از جمله کاربردهای استفاده از تکنیک دوباره نویسی آدرس های وب مخفی سازی تکنولوژی و زبان برنامه نویسی به کار رفته در ایجاد صفحات سایت و در عین حال داشتن آدرس های کوتاهتر و خواناتر است، به طور مثال می توانیم با نمونه دستور زیر عبارت index.php را از آدرس URL (با یک پارامتر) حذف کنیم:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?id=$1 [QSA,L]
طبق این دستور آدرس فرضی example.com/index.php?id=1 را می توانیم به صورت example.com/1 در سایت داشته باشیم.
نکته: با توجه به ساختار آدرس های سایت الگوی این سبک قوانین می تواند دامنه وسیعی از URL ها را شامل شود یا باعث ایجاد تداخل در قانون ها گردد، به همین دلیل و به صورت نمونه آیکن های ریشه سایت را با تعیین شرط از این قاعده مستثناء کرده ایم.

یادآوری مهم


در پایان این آموزش مجددا یادآور می شویم دوباره نویسی آدرس های وب باید با دقت بالا انجام شود، اشتباه در نحوه چینش قانون ها مخصوصا در مورد قوانین مشابه ممکن است موجب بروز اختلال در عملکرد عادی سایت شده یا سبب ایجاد مشکلاتی نظیر مطالب تکراری (Duplicate Content) گردد، بهتر است با سربرگ های HTTP آشنا و بر تکنیک ریدایرکت 301 (Moved Permanently) نیز تسلط کافی داشته باشیم و قبل از اعمال تغییرات در ساختار URL های سایت حتما همه ی جوانب را تست و از کدهای فعلی پشتیبان تهیه کنیم.
دسته بندی: مهارتهای وب » بهینه سازی
related مطالب بیشتر:
رتبه بندی الکسا (Alexa) چیست و چقدر اهمیت دارد؟!
حل مشکل محتوای تکراری (Duplicate Content) در سایت
مشکلات رایج در کدنویسی معتبر و رفع آنها
پیج رنک چیست و چگونه می توان آن را افزایش داد؟
چرا برخی سایت ها و وبلاگ ها رتبه الکسای بهتری دارند؟
دیدگاه
more ۱۹۵ دیدگاه برای این مطلب ارسال شده است.
more دیدگاه جدید بر اساس تاریخ ارسال در انتهای دیدگاه های موجود نمایش داده می شود.
pooya
۲۱:۳۳ ۱۴۰۰/۰۶/۱۹
سلام نام صفحات مختلف سایت را در دیتابیس ذخیره میکنم، چگونه می توان از نام این صفحات (در دیتابیس) برای url و لینک شدن اون صفحه استفاده کرد مثلا
به جای آدرس زیر :
example.com/index.php?id = 30
url به صورت زیر نمایش داده شود :
example.com/index/صفحه موردنظر
در گام اول باید لینک را در خروجی چاپ کنیم، برای این کار از دستور SELECT در MySQL استفاده می کنیم (آموزش های مربوطه در بخش مقدماتی MySQL وجود دارد)، پس از چاپ لینک ها در تگ a باید از دوباره نویسی آدرس URL استفاده کنیم، برای این مرحله در فایل htaccess نمونه دستور زیر را درج می کنیم:
RewriteEngine On
RewriteRule ^index/([^/]+)$ /index.php?id=$1[NC,L]
m.b
۲۱:۱۹ ۱۴۰۰/۰۷/۰۳
سلام و خسته نباشید جانانه به شما عزیزان که پاسخگوی سوالات هستید. سوالی داشتم از خدمتتان من یک تیبل دارم به نام newposts که دارای ستون های مختلفی از جمله img ,title, link, description, (عنوان - لینک - متن - عکس , ...) می باشد .
حالا من اطلاعات را از طریق فرم وارد دیتابیس می کنم و در صفحه سایت مثلا 1 www.site.ir/new میام فراخوانی می کنم .
درصورتی که مقاله جدید وارد دیتابیس شود به همراه عکس و عنوان و لینک مربوطه می خوام خودبخود لینک جدید ایجاد شود و در صفحه www.site.ir/new 2 مثلا قرار گیرد باید به چه روشی و چطوری کد نویسی شود که مثلا بعد از وارد شدن مقاله دوم در دیتابیس به همراه لینک ادرس new2 خودبخود صفحه جدید درست شود و نیاز به کپی کدهای صفحه اول به صفحه دوم و ویرایش آنها در صفحه دوم نباشد. در ادامه امکان نوشتن نمونه سورس کوتاهی هست که بشه کامل ترش کرد .. ممنون از اینکه وقت میزارید و جوابگو هستید.
سوالتان کلی است و پاسخ کوتاهی ندارد، در کل باید با برنامه نویسی PHP و کار با MySQL آشنا باشید، PHP برای ساخت صفحات وب به صورت داینامیک مناسب است یعنی همان هدفی که دنبال می کنید، معمولا CMS ها پارامترهای هر صفحه را از طریق متد GET در آدرس URL دریافت می کنند به فرض:
http://example.com/?posts.php?id=23
و در فایل posts.php از متد GET برای دریافت پارامتر استفاده می شود:
<?php
$post_id = $_GET['id'];
$sql = "SELECT * FROM `newposts` WHERE id = '$post_id'";
.
.
.
?>
نکته مهم اینکه باید نکات امنیتی دیتابیس را رعایت کنید و پارامترهایی که از بیرون برنامه دریافت می شوند را به دقت ایمن سازی کنید (با توابعی مانند mysqli_real_escape_string یا Prepared Statements و...)، آموزش تمام این موارد را در بخش مقدماتی PHP و MySQL گفته ایم.
دانیال
۲۰:۱۰ ۱۴۰۰/۰۸/۰۱
سلام ببخشید من می خواهم لینک از این:
http://localhost/post.php?post=php-learn
به :
http://localhost/post/php-learn
تغییر کنه، وقتی انجام میدم استایل ها و اسکریپت ها لود نمیشه و هم چنین نمیتونم مقدار
$_GET['post']
رو بدست بیاورم لطفا اگه میشه کد رو به من بگید که چطور هست؟ در ضمن فایل های پروژه کنار همه ، یعنی صفحه اصلی و صفحه پست در روت پروژه اند و استایل ها هم در
files/css/style.css
هست.
در مورد عدم بارگذاری فایل های CSS و JS مشکل از تغییر آدرس URL در مرورگر است، مرورگر آدرس های نسبی CSS و JS را بر اساس آدرس URL تنظیم و به سرور ارسال می کند به فرض اگر در حالت عادی آدرس به شکل زیر باشد:
<link rel="stylesheet" type="text/css" href="files/css/style.css">
مرورگر آدرس زیر را از سرور درخواست می کند:
http://localhost/files/css/style.css
اما با دوباره نویسی آدرس زیر درخواست می شود که اشتباه است:
http://localhost/post/php-learn/files/css/style.css
برای رفع مشکل دو راه حل وجود دارد، اول اینکه می توانیم آدرس را به شکل مطلق (کامل) در سورس HTML تنظیم کنیم نه به صورت نسبی، راه حل دوم آدرس دهی به شکل نمونه زیر است:
../../files/css/style.css
در مورد مشکل عدم دریافت پارامترها از متد GET به احتمال زیاد MultiViews در سرور فعال است، این قابلیت مربوط به Apache Content Negotiation (mod_negotiation) است که برای جلوگیری از تداخل فایل و فولدرهای هم نام در یک دایرکتوری بازنویسی شده استفاده و در مواردی (به فرض وقتی عبارت مشترکی مثل post در هر دو قسمت RewriteRule استفاده شده باشد) مانع از ارسال پارامترها می شود:
https://httpd.apache.org/docs/2.4/content-negotiation.html
برای رفع مشکل MultiViews را به شکل نمونه زیر غیرفعال کنید:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^post/([^/]+)$ /post.php?post=$1 [NC,L]
</IfModule>
دانیال
۰۰:۰۴ ۱۴۰۰/۰۸/۰۲
سلام دوباره
ببخشید من اون کد رو زدم جواب نداد خودم یه چیزی نوشتم:
function GetUrl(){
return "$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
}

$postID = GetUrl();
$postID = preg_replace("/\?.+/","",$postID);
$postID = explode('/',$postID);
echo end($postID);
من برای بازنویسی ادرس فارسی این رو نوشتم:
RewriteEngine On
RewriteRule post/*[0-9A-Za-zا-ی]+$ post.php/post=$1 [NC,L]
ولی از بعضی حروف مثل (ق) یا (ل) پشتیبانی نمیکنه و ارور ۴۰۴ بر می گردونه! باید تک تک حروف فارسی رو به عبارت قاعده دار اضافه کنم؟
راه حل خوبی است اما بهتر بود علت عدم دریافت پارامترها از متد GET در htacess مشخص می شد، استفاده از PHP برای حل این مشکل صرفا شیوه جایگزین و به اصطلاح کار راه انداز است!
استفاده از کاراکترهای خارج از استاندارد ASCII در دستورات htaccess توصیه نمی شود و متداول نیست، درج تک تک حروف فارسی به نظر روش جالبی نیست، چرا از این حالت استفاده نمی کنید تا مشکلات ناخواسته پیش نیاید؟:
RewriteRule ^post/([^/]+)$ /post.php?post=$1 [NC,L]
ظاهرا دستوراتتان هم ایراد دارد و اگر اصرار به استفاده از روش خودتان دارید باید به صورت زیر باشد:
RewriteRule ^post/([0-9a-z-آ-ی]+)$ /post.php?post=$1 [NC,L]
دانیال
۱۱:۵۴ ۱۴۰۰/۰۸/۰۲
سلام مجدد . ببخشید این همه سوال میکنم :)
من همونی که شما گفتید رو نوشتم
RewriteEngine On
RewriteRule ^post/([^/]+)$ /post.php?post=$1 [NC,L]
ولی آدرس به جای
http://localhost/post/php-learn
این جوری میشه:
http://localhost/post.php/php-learn
و اگه این رو بزنم
http://localhost/post/php-learn
این خطا رو بر می گردونه :
Not Found
The requested URL was not found on this server.
Apache/2.4.47 (Win64) OpenSSL/1.1.1k PHP/8.0.6 Server at localhost Port 80
نسخه ی لوکال هاستم هم xampp3.3.0 هست
دستور زیر را در ابتدای دستورات htaccess درج کرده اید؟:
Options -MultiViews
اگر مشکل رفع نشد اسم فایل post.php را به عبارت دیگری به فرض content.php تغییر دهید یا عبارت post در آدرس URL را به عبارت دیگری تغییر داده و تست کنید، در صورت عدم رفع مشکل نیاز به تست و بررسی آنلاین با برنامه TeamViewer است.
دانیال
۲۱:۲۷ ۱۴۰۰/۰۸/۰۲
سلام خیلی تشکر بابت راهنمایی شما :)
فقط من با
Options +MultiViews
کارم راه افتاد
بازم تشکر❤️
عجیب اینکه این مشکل معمولا با فعال بودن MultiViews رخ می دهد نه با غیرفعال بودن، در هر صورت خوشحالیم که مشکل رفع شد، ممنون از به اشتراک گذاری :)
۱۳:۳۹ ۱۴۰۰/۰۹/۰۲
سلام خسته نباشید من میخوام توی دامنه بر فرض مثال
www.example.ir/?artist=2&title=hello-word
بیام توی htaccess کاری کنم که به شکل
www.example.ir/2/hello-word
نمایش داده بشه، با توجه به اینکه بعد از دامنه اصلی مستقیما پارامتر get داریم.
برای بازنویسی آدرس با دو پارامتر داینامیک می توانید از نمونه دستور زیر در htaccess استفاده کنید:
RewriteEngine On
RewriteRule ^([0-9]+)/([a-z\-]+)$ /?artist=$1&title=$2 [NC,L]
دقت کنید این دستور با فرض ثابت بودن الگو (عدد به عنوان آی دی و حروف انگلیسی و کاراکتر - برای تیتر مطلب) نوشته شده است.
۱۹:۲۱ ۱۴۰۰/۱۱/۰۲
عالی بود
ali
۱۹:۲۲ ۱۴۰۰/۱۲/۰۲
سلام و عرض ادب
برای حذف blog از تمام یوارال های سایت چه کار باید انجام بدم؟
تمام مطالب سایت به اینصورته:
sitename/blog/ post1
sitename/blog/ post2
sitename/blog/ post3

لطفا راهنمایی بفرمایید
بازنویسی در شرایط مد نظر شما شامل چند مرحله است و باید خیلی دقت داشته باشید تا مشکلی ایجاد نشود، اول باید آدرس های استفاده شده در سورس HTML صفحات سایت بدون عبارت blog باشد (هیچ آدرسی با blog در صفحات نباشد) که یا باید از دیتابیس آدرس ها را به صورت گروهی تغییر دهید یا از طریق پنل مدیریت CMS، در گام بعد فایل htaccess فعلی را بررسی و ببینید دوباره نویسی به چه شکلی برای پارامتر blog/post انجام شده، سپس دستور زیر را اضافه کنید:
RewriteRule ^post([0-9]+)$ /index.php?post=$1 [NC,L]
در این دستور فایل فرضی index.php باید با توجه به CMS شما و مشابه با بخش دوم پارامتر blog/post که در بالا گفتیم باشد، در واقع چون ما شکل آدرس های سایت را تغییر می دهیم باید نحوه دوباره نویسی آنها هم تغییر کند.
در نهایت برای اینکه آدرس های قبلی به صورت خودکار به آدرس جدید منتقل شوند دستور زیر را برای انجام ریدایرکت 301 اضافه می کنیم:
RewriteRule ^blog/post([0-9]+)$ http://example.com/post$1 [R=301,L]
به جای example.com آدرس سایت خودتان را جایگزین کنید.
دقت کنید دستورات در سایتتان تست نشده و ممکن است با دستورات فعلی تداخل داشته باشند، لذا حتما ابتدا در بستر آزمایشی دستورات را امتحان و از فایل ها و اطلاعات دیتابیس پشتیبان داشته باشید.
ali
۱۶:۰۰ ۱۴۰۰/۱۲/۱۱
سلام مجدد و تشکر بابت پاسخ سریعتون
در وردپرس یک پست تایپ جدید ایجاد کردم و لینک پستها را به صورت زیر قراردادم مشکلی نداره
sitename/post_type/category-yek/post name  
ولی از لینک زیر یعنی دسته بندی ها هر دو در دسترس هستند
sitename/post_type/category-yek
و
sitename/category_slug/category-yek
چطور میتونم category_slug را به post_type تغیر بدم؟
ممنون میشم راهنمایی بفرمایید
اگر بخواهید فقط یک شکل آدرس URL در سایت برای پست ثابت وجود داشته باشد باید شکل های دیگر را با ریدایرکت 301 به آدرس اصلی منتقل کنید، به فرض:
RewriteRule ^category_slug/([^/]+)$ http://example.com/post_type/$1 [R=301,L]
با توجه به حساسیت بازنویسی آدرس ها بهتر است ضمن گرفتن پشتیبان از اطلاعات موجود، ابتدا در یک سایت آزمایشی یا در لوکال هاست تمام جوانب را بررسی و تست کنید، تغییر دستورات فایل htaccess بدون آشنایی و تسلط کافی توصیه نمی شود.
ali
۱۲:۱۳ ۱۴۰۰/۱۲/۱۲
من طبق آموزش زیر عمل کردم
https://stackoverflow.com/questions/23698827/custom-permalink-structure-custom-post-type-custom-taxonomy-post-name
و لینک پست تایپ جدید در سایت مپ به صورت زیر ثبت میشه
sitename/post_type/category-yek/post name  
ولی لینک کتگوری ها به صورت زیر
sitename/category_slug/category-yek
با کد بالا که شما فرمودید هم فقط ریدایرکت 301 میشه از
sitename/category_slug/category-yek
به
sitename/post_type/category-yek
نمیشه کاری کرد که در سایت مپ هم لینک اصلی ثبت بشه؟
ممنون از راهنمایهاتون
با توجه به توضیحات مشکل شما مربوط به تغییر ساختار خروجی وردپرس است نه صرفا بازنویسی یا ریدایرکت آدرس ها، متاسفانه در زمینه وردپرس خیلی فعال نیستیم، ممکن است راه حل ساده به فرض نصب پلاگین و تعریف فیلتر یا پیچیده مانند اعمال تغییرات چند قسمتی داشته باشد که در هر صورت نیازمند بررسی سورس ها و ارتباط بین بخش های مختلف این CMS است.
سینا
۲۰:۰۴ ۱۴۰۰/۱۲/۲۸
با سلام و خسته نباشید
ببخشید من برای سایتم ssl دارم توی سایت از wildcard استفاده می کنم روی ساب دامین هایی که با ویلدکارد استفاده می کنم ssl نصب نیست الان می خوام تنظیمات htaccess جوری باشه که سایت اصلی دایورت بشه روی ssl بدون www و ساب دامین ها که با ویلدکارد درست شدن همون بدون ssl باشند. قبلا توی یکی از فرومها تنظیماتش رو پیدا کرده بودم ولی متاسفانه گمش کردم
ممنون می شم کمکم کنید
با تشکر فراوان
برای ریدایرکت تمام آدرس ها به جزء ساب دامین ها به نسخه HTTPS نمونه دستور زیر را امتحان کنید:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(.*)\.example\.com [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
به جای example.com آدرس URL سایت خودتان را جایگزین کنید.
سینا
۲۳:۴۴ ۱۴۰۰/۱۲/۲۸
با تشکر از شماـ
من فرمایش شما رو انجام دادم استاد محتوای تنظیمات سایت من اینطوری شدـ
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php?/$1 [L,QSA]

Allow from env=BingRobot

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} !^(.*)\.example\.com [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
و این ارور رو داد!
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator at webmaster@example.com to inform them of the time this error occurred, and the actions you performed just before this error.
More information about this error may be available in the server error log.
قسمت مربوط به انتقال از HTTP به HTTPS در دستورات بالا ویرایش شد، لطفا تکه کد جدید را پس از جایگزینی عبارت example.com با آدرس URL سایت خودتان امتحان کنید.
سینا
۰۰:۳۱ ۱۴۰۱/۰۱/۰۱
از لطف شما بسیار ممنون و سپاسگزارم
این دفعه درست عمل می کنه ولی برای ریدارکت کردن https به http همون مثل سابق عمل می کنه یعنی وقتی از گوگل با https وارد سایت می شن باید بازم دکمه ارور رو بزنن که سایت از https به http براشون باز بشه تعدای از لینکهای با https توی گوگل ایندکس شدن من واسه اونا می خوام که کاربر بدون ارور به http ریدارکت بشه
با تشکر
در یادداشت های قبلی اشاره ای به این مورد نداشتید و دستور هم برای انتقال از HTTP به HTTPS ارائه شد، برای انتقال HTTPS به HTTP برای ساب دامین ها می توانید دستور زیر را استفاده کنید:
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^(.+)\.example\.com [NC]
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
نکته: کد تست نشده است!
۱۴:۱۹ ۱۴۰۲/۱۱/۰۷
سلام وقت بخیر استاد، من در سایتم ویدیوهای اموزشی دارم و میخوام با دستورات htaccess امکان دانلود آن را غیرفعال کنم ولی در مرورگر (سایت) برای کاربر پلی و نمایش داده شود.
چه دستوراتی میتونم بزارم؟
تشکر
ایجاد محدودیت دسترسی به فایل های ویدئویی به شکل مد نظر شما با دستورات htaccess به صورت نمونه زیر شدنی است (کد تست نشده):
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://example.com/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.example.com/.*$ [NC]
RewriteRule .(mp4|mp3|avi)$ - [F]
به جای عبارات example.com آدرس دامنه سایت خود را قرار دهید و فرمت فایل ها را هم در قسمت آخر تنظیم کنید.
متاسفانه موفقیت این روش صددرصدی نیست و همچنان امکان دانلود فایل در شرایطی وجود دارد، شاید بهترین حالت استفاده از ویدئوها در حالت Stream باشد که مبحث مفصل و جداگانه ای دارد.
more لطفا پیش از ارسال دیدگاه نکات زیر را مد نظر داشته باشید:
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.



 refresh
10 × 10
8 × 6
20 × 20
=
آخرین دیدگاه ها
more برای دسترسی سریع به یادداشت مربوطه می توانید از لینک مطلب در کادر زیر استفاده کنید.
پـــرتو
سلام خوبید؟ ببخشید مزاحم میشم یه سوال کامپیوتری داشتم اونم اینکه این خطای dll یعنی چی و چطوری رفع میشه ؟ بیشتر توی نرم افزارها...
۱۴۰۲/۱۲/۰۵

سعید
با تشکر از شما دوست عزیز درست شد. دست شما درد نکنه یه سوال دیگه هم دارم چطور میشه توی استایل تصاویر رو فیت...
۱۴۰۲/۱۲/۰۳

سعید
با تشکر از شما درست شد فقط یه مشکلی دارم میخوام شناسه اون مطلب رو اینطوری براش فراخوانی کنم ولی شناسه رو دریافت...
۱۴۰۲/۱۲/۰۲

سعید
با تشکر از شما خیلی خوب بود. فقط یه مشکلی داره، اگه لینک دانلود داخل عکس باشه کار نمی کنه و بازم لینک رو...
۱۴۰۲/۱۲/۰۲

سعید
با سلام و خسته نباشید من یه تابع با php میخوام که لینک های موجود در یک متن رو برام شناسایی کنه بعد به...
۱۴۰۲/۱۲/۰۱

روح اله
سلام چرا وبلاگ من در نتایج یاهو میاید ولی در نتایج گوگل نمیاید؟
۱۴۰۲/۱۱/۲۶

جواد
سلام خسته نباشید. من میخواستم تعداد نامحدودی عدد رو با هم جمع و تفریق کنم از کدوم حلقه باید در public function کلاسم استفاذه...
۱۴۰۲/۱۱/۲۵

محمد
سلام من گوشی نوکیای جاوا دارم که ساعت گویاش فعال شده و به صورت انگلیسی ساعت رو میگه میخواستم ببینم چطور میشه ساعت گویاش...
۱۴۰۲/۱۱/۲۳

پـــرتو
سلام خوبید؟ ممنون از راهنماییتون من ادرس وبلاگ رو براتون ایمیل کردم واقعا ممنونم مچکرم مرسی
۱۴۰۲/۱۱/۱۸

پـــرتو
سلام خسته نباشید ببخشید مزاحم میشم سوال قبلیم رو یادتونه که گفته بودم یه کد بدین که بشه عکس های داخل پست رو فیکس کنه...
۱۴۰۲/۱۱/۱۵

فاطمه
سلام وقت بخیر وب بازدید کننده داره ولی گویا آدرس وب برای برخی از افراد باز نمیشه چه کاری میتونم انجام بدم تا...
۱۴۰۲/۱۱/۰۹

سیاوش آهی
سلام وقت بخیر استاد، من در سایتم ویدیوهای اموزشی دارم و میخوام با دستورات htaccess امکان دانلود آن را غیرفعال کنم ولی در مرورگر (سایت)...
۱۴۰۲/۱۱/۰۷

پـــرتو
خب الان این تگ رو کجا بزارم؟ و تاثیر سراسری یعنی چی؟؟ در مورد هارد هم منظورتون از چندنمونه فایل در دسترس باشد یعنی چی؟؟؟...
۱۴۰۲/۱۱/۰۵

سجاد
با سلام و خسته نباشید من برای جستجو از این فرم استفاده می کنم رو انتخاب می کنم گزینه های جستجو بر...
۱۴۰۲/۱۱/۰۳

پـــرتو
سلام خسته نباشید ببخشید مزاحم میشم می خواستم یه سوال بپرسم اونم اینکه من یه مشکلی کدم داره اینکه عکس وقتی داخل پست می گذارم...
۱۴۰۲/۱۰/۲۸

مریم
سلام. من از قالب های سایت پیچک که استفاده میکنم مطالب رو نشون نمیده و به جاش مینویسه archive title. اما از قالب های پیش...
۱۴۰۲/۱۰/۲۶

بهاره هوشمندی
توی اکشن callback فقط کوئری ها هستند و من دستور die رو جای مناسب گذاشتم چون جای دیگه نمیشه گذاشت! این کوئری ها هستند که...
۱۴۰۲/۱۰/۲۳

بهاره هوشمندی
با تشکر از شما استاد بزرگوار اینو تست کردم لینک رو به درستی شناسایی نمی کنه و ارور میده! وگرنه همون مسیر خودش رو...
۱۴۰۲/۱۰/۲۳

بهاره هوشمندی
با سلام استاد با sleep نمیشه متن به کاربر نشون داد فقط میشه تاخیر ایجاد کرد واسه همین die بهتره ولی من نمی دونم...
۱۴۰۲/۱۰/۲۳

بهاره هوشمندی
با سلام و خسته نباشید واسه ترجمه از این تابع استفاده میکنم
۱۴۰۲/۱۰/۲۲

بهاره هوشمندی
با سلام متاسفانه هرکاری کردم نشد! یه هفته ست درگیرش هستم انگار هیچ راهی نداره البته احتمالا به دستور die باشه ولی اون...
۱۴۰۲/۱۰/۲۱

بهاره هوشمندی
با سلام و خسته نباشید وقتی میخوام با گوگل ترانسلیت متنی رو با php ترجمه کنم عکس ها رو خراب می کنه چون توی...
۱۴۰۲/۱۰/۲۱

بهاره هوشمندی
من تونستم یه جوری کدها رو توی قالب بذارم ولی چون کال بک اصلا فایل ویو نداره و یک چک کنه است هیچ جوری پیام...
۱۴۰۲/۱۰/۱۹

بهاره هوشمندی
با تشکر از شما من فقط اکشنش رو دارم که اکشن به تنهایی کار نمی کنه! :( الان این کد رو توی قالب...
۱۴۰۲/۱۰/۱۹

بهاره هوشمندی
با سلام و با تشکر از شما استاد خیلی خوب بود من توی فریمورک yii صفحه callback ندارم کاربر زمان زیادی برای اکشن...
۱۴۰۲/۱۰/۱۸

بهاره هوشمندی
با سلام لینک رو نگاه کردم خوب بود ولی من میخوام برای کاربر بنویسم که تا ۱۰ ثانیه صبر کنه که کاربر صفحه رو...
۱۴۰۲/۱۰/۱۸

بهاره هوشمندی
با سلام و خسته نباشید استاد لود کردن کوئری های سایت من واسه یه صفحه زیاده و ۱۰ تا ۱۵ ثانیه طول میکشه که...
۱۴۰۲/۱۰/۱۷

سجاد مهدوی
با سلام ببخشید می تونید توی سایت نوبیتکس ثبت نام کنید و با api هایی که دادن یه کد بنویسید که اعلام موجودی رو...
۱۴۰۲/۱۰/۱۰
  در انتظار بررسی: ۱
 پاسخگویی به سوالات ممکن است تا ۲۴ ساعت زمان ببرد.