מאמרים ASP.NET: הגדרת דף מתואם אישית עבור שגיאת 404 ו-SEO

danielkatz

משתמש צעיר
D I G I T A L
מה בין שגיאות 404, asp.net וseo? - כרגיל, asp.net לא נבנה תוך התחשבות בצרכי seo, וכך, שוב, פעולות טריביאליות לכאורה הופכות למורכבות יותר.

כידוע, הדרך הקלה ביותר להגדיר עמוד מתואם אישית לשגיאות 404 בasp.net הוא להגדיר את customErrors בweb.config, כך:

קוד:
<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />

[B]    <customErrors mode="On">
      <error statusCode="404" redirect="error404.aspx"/>
    </customErrors>
[/B]  </system.web>

</configuration>

רק שכאן נוצרת בעיית seo גדולה. בואו נראה את תשובות הhttp שמחזיר אתר שמוגדר כך:
צפה בקובץ המצורף 72980

ניסיתי לטעון דף בשם unexisted (לא קיים), ואז קיבלתי קוד מצב 302 (הפנייה זמנית) לדף error404.aspx, וממנו קיבלתי קוד מצב 200 (OK). אין בכלל קוד מצב 404!!

אפילו יותר גרוע אם מוגדר redirectMode=ResponseRewrite, במקרה כזה יתקבל רק קוד מצב 200!

ממה בעצם מורכבת שגיאת 404?

בפרוטוקול HTTP, כשלקוח (בדרך כלל דפדפן) מבקש משרת דף מסוים, השרת מחזיר לו 4 קטגוריות של נתונים:
  1. גרסת הפרוטוקול שלפיה נבנתה הודעת התשובה.
  2. קוד מצב (status code) המציין את התוצאה של ניסיון השרת למלא את הבקשה שנשלחה. הקוד מורכב ממספר תלת-ספרתי והסבר טקסטואלי קצר על משמעותו.
  3. שדות כותרת (headers) המכילים מידע על הודעת התשובה ועל השרת.
  4. גוף הודעה שתוכנו תלוי בשיטת הבקשה ובקוד המצב.
שגיאת 404 היא, בראש ובראשונה, קוד מצב, שמחזיר השרת, במקרה שהכתובת המצוינת בבקשה לא תואמת אף אובייקט שנמצא על השרת.
ולמה הקוד חשוב, הלא בדף error404.aspx מוצג ללקוח שהדף לא נמצא? - SEO. מצוטט ממסמך "יצירת דפי 404 שימושיים" של גוגל:

"לא משנה כמה יפה ושימושי דף 404 שלך יהיה, מן הסתם לא תרצה שהוא יופיע בתוצאות החיפוש של Google. כדי למנוע הוספת דפי 404 לאינדקס של Google, ודא ששרת האינטרנט שלך מאחזר קוד מצב HTTP 404 אמיתי כאשר יש בקשה לדף חסר."

כלומר, רובוט (זחלן) לא יבין שזו שגיאת "דף חסר" אא"כ הוא יקבל קוד מצב 404. ובמימוש ברירת המחדל של asp.net לא תהיה לו מניעה מלהוסיף קישור שבור לאינדקס. דבר שגורם, לכפילות תוכן (דפי 404 רבים זהים), ולבלבול הגולשים שיקבלו דפים לא קיימים בתוצאות החיפוש.

אציע שני פתרונות לבעיה

פתרון א':
מעלות: פשוט למימוש.
חסרונות: ישים רק לדפי שגיאה דינמיים לדוגמה (error404.aspx), ולא לדפי שגיאה סטטיים (error404.html).

להגדיר בweb.config כך:

קוד:
<customErrors mode="On" [B]redirectMode="ResponseRewrite"[/B]>
  <error statusCode="404" redirect="error404.aspx"/>
</customErrors>

ובדף השגיאה (error404.aspx) לכתוב כך:

קוד:
<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
[B]        Response.StatusCode = 404;[/B]
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>404 Not Found</title>
</head>
<body>
    <form id="form1" runat="server">
    <h1>404 Not Found</h1>
    </form>
</body>
</html>

פתרון ב':
מעלות: מתאים גם לדפי שגיאה סטטיים (error404.html). מניח יסוד למימוש נכון של קודי שגיאה נוספים.
חסרונות: קוד לא "הצהרתי" (declarative).

בweb.config אין להגדיר הדפי שגיאה כלל:

קוד:
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    
[COLOR="grey"]    <!--<customErrors mode="On" redirectMode="ResponseRewrite">
      <error statusCode="404" redirect="error404.aspx"/>
    </customErrors>-->
[/COLOR]  </system.web>
</configuration>

ובGlobal.asax לממש את Application_Error בצורה הבאה:

קוד:
void Application_Error(object sender, EventArgs e)
{
    HttpException ex = Server.GetLastError() as HttpException;
    if (ex != null)
    {
[B]        Response.StatusCode = ex.GetHttpCode();[/B]

        switch (Response.StatusCode)
        {
            case 404:
                Server.Transfer([B]"~/error404.htm"[/B]);
                break;
            default:
                Server.Transfer("~/error.htm");
                break;
        }
    }
}

שני הפתרונות האלו יביאו לתוצאה הרצויה, קוד מצב 404:
צפה בקובץ המצורף 72981

אשמח לקבל תגובות, והצעות למאמרים הבאים בסדרה!
 

קבצים מצורפים

  • 302-200.PNG
    KB 5.1 · צפיות: 0
  • Solution.PNG
    KB 2.8 · צפיות: 0

חיים פ

משתמש צעיר
אם כבר מדברים על דפי שגיאה..
עקרונית חשיפת הStatus Codes למשתמשים מחוץ לשרת היא פירצת אבטחה. פורץ יכול להשתמש בסטאטוסים שחוזרים במהלך עבודתו כדי לגלות חולשה במערכת.
ולכן יש להחזיר את אותה הודעת שגיאה תמיד לכל סוג של שגיאה..
הנה קישור להודעת מייקרוסופט:
http://www.microsoft.com/technet/security/advisory/2416728.mspx
ולבלוג של Scott gu לפירוט החולשה ולטיפול בה (לא מסובך):
http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx
 

danielkatz

משתמש צעיר
D I G I T A L
חשיפת Status Codes למשתמשים מחוץ לשרת היא תקן וחובה

נכתב ע"י חיים פ;466509:
אם כבר מדברים על דפי שגיאה..
עקרונית חשיפת הStatus Codes למשתמשים מחוץ לשרת היא פירצת אבטחה. פורץ יכול להשתמש בסטאטוסים שחוזרים במהלך עבודתו כדי לגלות חולשה במערכת.
ולכן יש להחזיר את אותה הודעת שגיאה תמיד לכל סוג של שגיאה..
הנה קישור להודעת מייקרוסופט:
http://www.microsoft.com/technet/security/advisory/2416728.mspx
ולבלוג של Scott gu לפירוט החולשה ולטיפול בה (לא מסובך):
http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx

אם היית קורא את המאמרים אליהם צירפת לינק, היית לומד, שחסימת הStatus Codes הוא רק פתרון זמני (workaround)לבעיה שאינה קיימת עוד.
 

חיים פ

משתמש צעיר
אתה צודק.
קראתי את המאמר הזה לפני שמייקרוסופט הפיצו את העדכון בסוף החודש שעבר.
ו-כמובן שצריך לסמוך על חברת איחסון האתרים שלך שתתעדכן תמיד..
 

אולי מעניין אותך גם...

הפרק היומי

הפרק היומי! כל ערב פרק תהילים חדש. הצטרפו אלינו לקריאת תהילים משותפת!


תהילים פרק קכא

א שִׁיר לַמַּעֲלוֹת אֶשָּׂא עֵינַי אֶל הֶהָרִים מֵאַיִן יָבֹא עֶזְרִי:ב עֶזְרִי מֵעִם יְהוָה עֹשֵׂה שָׁמַיִם וָאָרֶץ:ג אַל יִתֵּן לַמּוֹט רַגְלֶךָ אַל יָנוּם שֹׁמְרֶךָ:ד הִנֵּה לֹא יָנוּם וְלֹא יִישָׁן שׁוֹמֵר יִשְׂרָאֵל:ה יְהוָה שֹׁמְרֶךָ יְהוָה צִלְּךָ עַל יַד יְמִינֶךָ:ו יוֹמָם הַשֶּׁמֶשׁ לֹא יַכֶּכָּה וְיָרֵחַ בַּלָּיְלָה:ז יְהוָה יִשְׁמָרְךָ מִכָּל רָע יִשְׁמֹר אֶת נַפְשֶׁךָ:ח יְהוָה יִשְׁמָר צֵאתְךָ וּבוֹאֶךָ מֵעַתָּה וְעַד עוֹלָם:
נקרא  1  פעמים

לוח מודעות

למעלה