הפניית גולשים לאתר מותאם בשרת Apache

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

אופנת פיתוח האתרים היום הינה אתרים ריספונסיביים, ובצדק רב. אתר ריספונסיבי נותן את חווית הגלישה הטובה ביותר לכל גולש שיגיע אליו, לא משנה מאיזה מכשיר. אבל אתרים ריספונסיביים אינם נטולי בעיות: מאחר והריספונסיביות בנויה כולה בצד הלקוח, מכשירי טלפון חלשים מקבלים את אותו קןד HTML, JavaScript ו CSS כמו מכשירים חזקים מהם בהרבה, דבר שעלול לפגוע בביצועים. חסרון נוסף הוא שיש גבול להתאמות שאפשר לבצע כשאנו טוענים את אותו ה HTML, בפרט אם מדברים על Mobile Web Applications, כלומר אתר שמתנהג לכל דבר ועניין כמו אפליקציה. 

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

1. הפניית גולש על שרת Apache

שרת Apache מאפשר הוספת קונפיגורציה ספציפית לתיקייה באמצעות קובץ .htaccess. כדי להפנות גולשי מובייל אנו נכתוב קובץ הגדרות כזה לאתר שלנו. אין צורך להתחיל הכל מאפס ואפשר לקחת סקריפט מוכן למשל מהאתר הזה:
http://detectmobilebrowsers.com/

כך נראה קובץ ההגדרות שהורדתי מהם עבור שרת Apache:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTP_USER_AGENT} (android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|mobile.+firefox|netfront|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ ce|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-) [NC]

RewriteRule ^$ http://detectmobilebrowser.com/mobile [R,L]

 

קחו את הסקריפט שלמעלה ושמרו אותו בתור קובץ .htaccess, ולאחר מכן החליפו את הכתובת בשורה האחרונה בסקריפט לכתובת אליה תרצו לנתב גולשים ממכשירי מובייל. שימו לב לסימן הנקודה בתחילת שם הקובץ. כדי לבדוק שההפניה עובדת. נכנס לכלי הפיתוח של כרום, נלחץ על כפתור הדמיית הטלפון, ולאחר מכן נבחר דגם סלולרי. רענון הדף יביא אתכם לכתובת החדשה כפי שרואים בתמונה (שימו לב לשני החיצים באיור שמראים את הפעולות לביצוע):

 

2. התאמת ההפניה גם לעמודים פנימיים

קוד ההפניה הנוכחי מתאים את הגולשים שמגיעים לכתובת הראשית שלכם, אך לא לעמודים פנימיים. זה אומר שאם מישהו משתף קישור לאתר ממכשיר Desktop ולאחר מכן גולש אחר מגיע דרך הקישור הפנימי ממכשיר Mobile, אותו גולש מובייל יקבל את האתר הרגיל ולא האתר המותאם.

אם האתר שלכם בנוי בתור Mobile Web Application ועונה על נתיבים אחרים, או בכלל בנוי אחרת מהאתר הרגיל, זה פחות או יותר הטוב ביותר שתוכלו לספק. אבל, אם יש התאמה בין המסכים של האתר המותאם לנתיבים באתר הרגיל, אפשר לעדכן את ההפניה כך שתביא את הגולש גם פנימה לעמוד פנימי באופן הבא:


RewriteBase /

RewriteCond %{HTTP_USER_AGENT} (android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|mobile.+firefox|netfront|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ ce|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-) [NC]
RewriteRule ^(.*)$ https://m.example.com/$1 [R,L]

 

3. הפניה לאתר הרגיל

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

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

<a href="/?desktop=1">Desktop Site</a>

בקוד הניתוב אנו נוסיף בדיקת פרמטר זה, ונבצע את הניתוב רק במידה ופרמטר זה לא מופיע. כך נראה הקוד המעודכן:

RewriteEngine On
RewriteBase /

RewriteCond %{QUERY_STRING} !\bdesktop=1
RewriteCond %{HTTP_USER_AGENT} (android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge\ |maemo|midp|mmp|mobile.+firefox|netfront|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ ce|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-) [NC]
RewriteRule ^(.*)$ https://m.example.com/$1 [R,L]

התנאי הראשון מוודא שהפרמטר desktop לא מופיע בשורת הפרמטרים (או שמופיע עם ערך שונה מ-1), ורק במצב כזה ממשיך בתהליך הניתוב. 

4. סיכום וקריאת המשך

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

ניתוב לאתר מותאם מביא עמו שני חסרונות מרכזיים:

  1. מבחינת ביצועים, לקוח שמגיע מדפדפן Mobile מקבל תגובת HTTP Redirect, מה שמגדיל את זמן טעינת העמוד עבורו (גם אם לאחר מכן העמוד שיקבל יהיה רזה יותר ויעבוד חלק יותר, הנזק לעתים כבר נעשה).
  2. הפתרון דורש התאמות ותחזוקה כל הזמן. הסקריפט שהצגתי מתאים למצב השוק נכון לסוף 2014,. עם הזמן מכשירי טלפון חדשים יוצאים, חלקם מכוסים ברשימת ה User Agents שבסקריפט, אך חלקם יגיעו עם מחרוזת User Agent שלא מתאימה לרשימה, ולכן עלינו לעדכן רשימה זו באופן תדיר. 
    זאת בניגוד לאתר ריספונסיבי המותאם גם למכשירים עתידיים.

ניתוב באמצעות .htaccess מהיר יותר מאשר ניתוב בתוך שפת התכנות שלכם (PHP או כל סביבה אפליקטיבית אחרת). ראינו גם כיצד שימוש ב Query String Parameter מאפשר למשתמשים לגשת לאתר בגירסת ה Desktop שלו, גם בגישה ממכשירי מובייל.

קריאה נוספת בנושא:

  1. התאמת אתר Mobile למנועי חיפוש:
    https://developers.google.com/webmasters/mobile-sites/mobile-seo/configurations/separate-urls
  2. טעויות נפוצות בעת פיתוח אתרים מותאמים:
    http://practisinc.com/avoid-common-mobile-website-mistakes/