הפניות 301

טבלת redirections, פאנל הניהול שלה, האלגוריתם של ROUTER::redirections, והשלב ברצף הבקשה שבו הפניה נבדקת, כולל המלכודת של מטמון העמודים.

⏱ 3 דק' קריאה 594 מילים ערוך דף זה ב-GitHub

כשכתובת עוברת למקום חדש, מוסיפים שורה בטבלה CRM_redirections והליבה עונה 301 Moved Permanently עם כותרת Location. ההפניות הן התאמה מדויקת של נתיב לנתיב: אין תבניות ואין wildcard (לביטויים רגולריים משתמשים ב-seoUrl, שמתרגם כתובת לנתיב פנימי אבל לא מפנה).

system/ בעמוד הזה הוא תיקיית הליבה הפרוסה (api/core בריפו), ו-{admin} הוא CONFIG::$admin_url.

הטבלה והפאנל#

עמודהמשמעות
idמפתח
url_fromהנתיב הישן, בלי / בהתחלה ובסוף ובלי מחרוזת שאילתה
url_toהיעד: נתיב יחסי לאתר, או כתובת מלאה

הפאנל ADMINMODULE_redirections (system/admin/redirections.php, הכתובת {admin}/redirections) מציג רשימה ופותח טופס בחלון קופץ עם שני שדות: "מכתובת" (חובה) ו"לכתובת". לפני השמירה הוא מסיר מכל שדה את CONFIG::$site_url ומקצץ / מההתחלה ומהסוף, כך שאפשר להדביק כתובת מלאה מהדפדפן. שמירה ומחיקה מנקות את המטמון redirections.

הוספה מקוד#

$q = DB::update("redirections");
$q->set_var("url_from", "old-products/shoes");
$q->set_var("url_to", "products/shoes");
$q->insert();

cache_engine::remove("redirections");   // בלי זה הכלל לא ייראה עד שהמטמון יפוג

גם מ-SQL אפשר, ובלבד שמנקים את המטמון אחר כך:

INSERT INTO CRM_redirections (url_from, url_to) VALUES ('old-page', 'new-page');

האלגוריתם#

ROUTER::redirections() נקרא מ-PAGE::load מיד אחרי ROUTER::parse_friendly_url, ורק בצד לקוח (CONFIG::$system_type == "client"). הוא:

  1. טוען את כל הטבלה כמפה url_from => url_to, במטמון redirections ל-7 ימים.
  2. לוקח את $_SERVER['REQUEST_URI'], מקצץ / מהקצוות ומפצל ב-? לנתיב ולמחרוזת שאילתה.
  3. מחפש את הנתיב במפה, ואם לא נמצא, מחפש את urldecode שלו (כתובות בעברית).
  4. אם נמצא: אם היעד לא מכיל את המחרוזת http, מוסיף לו / בהתחלה. מחרוזת השאילתה המקורית מצורפת ליעד (עם & אם ביעד כבר יש ?, אחרת עם ?).
  5. שולח 301 ו-Location ומסיים את הבקשה עם exit.
url_fromurl_toבקשהתשובה
old-pagenew-page/old-page301 Location: /new-page
old-pagenew-page/old-page?ref=mail301 Location: /new-page?ref=mail
old-pagenew-page?a=1/old-page?ref=mail301 Location: /new-page?a=1&ref=mail
old-pagehttps://example.org/x/old-page301 Location: https://example.org/x
ההשוואה היא מחרוזת מדויקת
Old-Page, old-page/ עם תוספת נתיב, או בקשה עם ? שאינה חלק מה-url_from לא יתאימו אלא אם יש להם שורה משלהם. מחרוזת שאילתה בתוך url_from לעולם לא תתאים, כי הנתיב מופרד מהשאילתה לפני ההשוואה. הבדיקה של "האם הכתובת היא חיצונית" היא strpos($url_to, "http"): יעד פנימי שמכיל את http בכל מקום (למשל docs/http-codes) יטופל כחיצוני ויישלח בלי / בהתחלה.

אין הגנה מפני לולאות

הליבה לא בודקת שהיעד אינו מפנה בחזרה. שתי שורות a => b ו-b => a יחזירו את הדפדפן ללולאה עד שהוא ייכשל. שרשרת a => b => c עובדת, אבל כל חוליה היא בקשה נוספת: עדיף להפנות ישירות ליעד הסופי. הסריקה של חבילת ה-SEO מזהה לולאות, שרשראות ויעדים ריקים בטבלה.

איפה זה נבדק ברצף הבקשה#

ההפניה נבדקת אחרי הניתוב וה-MODULE עוד לא רץ, אבל היא מגיעה רק אם הבקשה הגיעה ל-PAGE::load. שני דברים קודמים לה:

  • מטמון עמודים מלא. cache_engine::cache_php_check רץ לפני PAGE::load. אם לכתובת הישנה כבר יש עותק ב-מטמון העמודים, הוא יוגש ישירות והשורה בטבלה לא תיבדק עד שהעותק יפוג או יימחק. אחרי שמוסיפים הפניה לכתובת שהייתה חיה, נקו את המטמון של הכתובת הזו (ניקוי ותחזוקה).
  • תשובות מוקדמות של הניתוב. נכסים סטטיים מ-assets/, pjs.js, pg.js ודומיהם מוגשים ומסתיימים בתוך parse_friendly_url, לפני בדיקת ההפניות. כתובת שמתפרשת בשלבים האלה (או ש-die("router error") מסיים אותה) לא תופנה.

הפניה גוברת על קונטרולר: אם url_from זהה לנתיב של מודול קיים, המודול לא ירוץ.

ראו גם#

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