گوگل خلاصه نتایج Indexing یک سایت را توسط ابزاری به نام Google webmaster tools در اختیار علاقمندان قرار میدهد. Bing نیز چنین ابزاری را تدارک دیده است.
به آمارهای خطای حاصل از سایت جاری که دقت میکردم یک نکته آن جالب بود: «محتوای تکراری»
همانطور که ملاحظه میکنید، گوگل به کوچکی و بزرگی حروف بکار رفته در لینکها حساس است. هرچند 4 لینک فوق به یک صفحه اشاره میکنند، اما گوگل 4 بار آنها را ایندکس خواهد کرد و نهایتا به صورت یک خطای «محتوای تکراری» در گزارشات SEO آن ظاهر خواهد شد (به همراه کاهش رتبه SEO سایت).
راه حل
برای حل این مساله دو نکته باید درنظر گرفته شود:
الف) هدایت دائمی (Redirect permanent) صفحات قدیمی به صفحاتی جدید، با آدرس lowercase
کلاس فوق، نگارش تکمیل شده ForceWww که پیشتر در این سایت دیدهاید. توسط آن سه بررسی مختلف بر روی لینک جاری در حال پردازش صورت خواهد گرفت:
- تمام آدرسهای سایت باید www داشته باشند؛ تا آدرسهای آن یکنواخت شده و خصوصا مشکلات لاگین و نوشته شدن کوکیها به ازای آدرسهای مختلف و سر درگمی کاربران کاهش یابد.
- اگر آدرس جاری lowercase نباشد، تبدیل به نمونه lowercase شده و درخواست کننده، به آدرس جدید هدایت میشود. این مورد خصوصا جهت موتورهای جستجو برای تصحیح نتایج آنها بسیار مفید است.
- اسلش انتهای لینکها در صورت وجود حذف خواهد شد. این مورد نیز در کاهش تعداد خطاهای «محتوای تکراری» مؤثر است.
- اگر آدرسی، کوئری استرینگ داشته باشد از آن صرفنظر خواهد شد؛ زیرا ممکن است اطلاعات موجود در آن به کوچکی و بزرگی حروف حساس باشند.
ب) کاهش بار سایت توسط تولید خودکار Urlهایی که در بدو امر lowercase هستند
برای پیاده سازی این مطلب میتوان از پروژه سورس باز «LowercaseRoutesMVC» استفاده کرد. سه فایل cs دارد که میتوانید به پروژه خود اضافه کنید. پس از آن، هرجایی در پروژه خود routes.MapRoute دارید تبدیل کنید به routes.MapRouteLowercase .
به این ترتیب به صورت خودکار تمام Urlهای تولید شده توسط HTML helpers توکار ASP.NET MVC (و نه Urlهایی که دستی نوشته شدهاند)، در حین درج در صفحه به صورت lowercase ظاهر خواهند شد (صرفنظر از اینکه نامهای کنترلرها و یا اکشن متدهای تعریف شده camel case هستند یا خیر). مزیت این مساله کاهش یک مرحله Redirect است که در قسمت الف ذکر شد. در این کتابخانه کمکی نیز از آدرسهایی که دارای کوئری استرینگ باشند، صرفنظر میشود.
به آمارهای خطای حاصل از سایت جاری که دقت میکردم یک نکته آن جالب بود: «محتوای تکراری»
mydomain.com/Home/Index mydomain.com/home/index mydomain.com/Home/index mydomain.com/home/Index
راه حل
برای حل این مساله دو نکته باید درنظر گرفته شود:
الف) هدایت دائمی (Redirect permanent) صفحات قدیمی به صفحاتی جدید، با آدرس lowercase
using System.Globalization; using System.Web; using System.Web.Mvc; namespace WebToolkit { public class ForceWww : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { modifyUrlAndRedirectPermanent(filterContext); base.OnActionExecuting(filterContext); } private static void modifyUrlAndRedirectPermanent(ActionExecutingContext filterContext) { if (canIgnoreRequest(filterContext)) return; var absoluteUrl = HttpUtility.UrlDecode(filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri.ToString(CultureInfo.InvariantCulture)); var absoluteUrlToLower = absoluteUrl.ToLowerInvariant(); absoluteUrlToLower = forceWwwAndLowercase(filterContext, absoluteUrlToLower); absoluteUrlToLower = avoidTrailingSlashes(filterContext, absoluteUrlToLower); if (!absoluteUrl.Equals(absoluteUrlToLower)) { filterContext.Result = new RedirectResult(absoluteUrlToLower, permanent: true); } } private static string avoidTrailingSlashes(ActionExecutingContext filterContext, string absoluteUrlToLower) { if (!isRootRequest(filterContext) && absoluteUrlToLower.EndsWith("/")) return absoluteUrlToLower.TrimEnd(new[] { '/' }); return absoluteUrlToLower; } private static bool isRootRequest(ActionExecutingContext filterContext) { return filterContext.RequestContext.HttpContext.Request.Url.AbsolutePath == "/"; } private static bool canIgnoreRequest(ActionExecutingContext filterContext) { return filterContext.IsChildAction || filterContext.HttpContext.Request.IsAjaxRequest() || filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri.Contains("?"); } private static string forceWwwAndLowercase(ActionExecutingContext filterContext, string absoluteUrlToLower) { if (isLocalRequet(filterContext)) return absoluteUrlToLower; if (absoluteUrlToLower.Contains("www")) return absoluteUrlToLower; return absoluteUrlToLower.Replace("http://", "http://www.") .Replace("https://", "https://www."); } private static bool isLocalRequet(ActionExecutingContext filterContext) { return filterContext.RequestContext.HttpContext.Request.IsLocal; } } }
- تمام آدرسهای سایت باید www داشته باشند؛ تا آدرسهای آن یکنواخت شده و خصوصا مشکلات لاگین و نوشته شدن کوکیها به ازای آدرسهای مختلف و سر درگمی کاربران کاهش یابد.
- اگر آدرس جاری lowercase نباشد، تبدیل به نمونه lowercase شده و درخواست کننده، به آدرس جدید هدایت میشود. این مورد خصوصا جهت موتورهای جستجو برای تصحیح نتایج آنها بسیار مفید است.
- اسلش انتهای لینکها در صورت وجود حذف خواهد شد. این مورد نیز در کاهش تعداد خطاهای «محتوای تکراری» مؤثر است.
- اگر آدرسی، کوئری استرینگ داشته باشد از آن صرفنظر خواهد شد؛ زیرا ممکن است اطلاعات موجود در آن به کوچکی و بزرگی حروف حساس باشند.
ب) کاهش بار سایت توسط تولید خودکار Urlهایی که در بدو امر lowercase هستند
برای پیاده سازی این مطلب میتوان از پروژه سورس باز «LowercaseRoutesMVC» استفاده کرد. سه فایل cs دارد که میتوانید به پروژه خود اضافه کنید. پس از آن، هرجایی در پروژه خود routes.MapRoute دارید تبدیل کنید به routes.MapRouteLowercase .
به این ترتیب به صورت خودکار تمام Urlهای تولید شده توسط HTML helpers توکار ASP.NET MVC (و نه Urlهایی که دستی نوشته شدهاند)، در حین درج در صفحه به صورت lowercase ظاهر خواهند شد (صرفنظر از اینکه نامهای کنترلرها و یا اکشن متدهای تعریف شده camel case هستند یا خیر). مزیت این مساله کاهش یک مرحله Redirect است که در قسمت الف ذکر شد. در این کتابخانه کمکی نیز از آدرسهایی که دارای کوئری استرینگ باشند، صرفنظر میشود.