אחד מה-Web API שזמינים לג'אווהסקריפט שרץ בסביבת דפדפן הוא ה-Visibility API. סוג של מנגנון קטן לבדיקה אם המשתמש מסתכל על החלון שבו הקוד רץ או לא. כלומר אם אני בפוקוס על הדפדפן כן או לא. אם אני יוצא מהפוקוס ועובר לטאב אחר או לאפליקציה אחרת – אז יהיה אירוע שיצא בג'אווהסקריפט שאפשר לתפוס אותו ואז לעשות פעולות מסוימות.
בואו ונראה את הדמו המהיר ואז נדבר על ההשלכות.
אז מבחינת דמו – הנה הקוד הבאמת פשוט:
document.addEventListener(
'visibilitychange',
() => {
if (document.hidden) {
console.log("the document is not visible");
} else {
console.log("the document is visible");
}
}
);
אין יותר מדי מה לחפור עליו. הנה גרסת ה-codepen:
אם תריצו את ה-codepen ותסכלו על הקונסולה, תוכלו לראות שבכל פעם שאתם יוצאים מהפוקוס/עוברים לשונית/בורחים לאפליקציה אחרת – יש אירוע שנורה על עזיבה – ובכל פעם שאתם חוזרים יש אירוע שחוזר חזרה.
בדוגמה השתמשתי ב-console.log, אבל כמובן שאפשר לעשות מה שרוצים. וזה מביא אותנו לנקודה הבאה:
למה צריך את זה?
בגדול זה יכול להיות מאוד שימושי באתרי ניגון וידאו או אודיו – שימו את האירוע הזה ואם המשתמש עוזב את הדף תוכלו לעצור את ההזרמה של המידע. אם יש לכם פעילות אינטראקטיבית כלשהי אז כנ"ל. זה באמת יכול לעשות את החיים של המשתמשים קלים יותר.
אבל, זה גם יכול לעשות את החיים של המשתמשים קשים הרבה יותר – כי זה יכול להיות דליפת פרטיות חמורה ממש. תחשבו למשל על מעסיק שבא לו לעשות מיקרו מנג'מנט לעובדים כדי לראות כמה פעמים הם מפוקסים בתוך ה-CMS שהם אמורים לעבוד עליו. או כל מישהו אחר שיש לו כוח מאוד גדול על החיים של המשתמשים שלו. כמו מערכת רווחה/ תמיכה וכו'. או ממש לצרכים אפלים כמו למשל סקריפט תקיפה שמרמה את המשתמשים ש"ההאקר" רואה אותם ואוסר עליהם לצאת מהחלון. באמת לא חסר כל מיני דוגמאות זדוניות. ובניגוד ל-API אחרים, פה אין צורך בהרשאות נוספות. יש את זה בכל דפדפן. אם תסתכלו ב-caniuse תראו שזה נתמך אפילו באקספלורר 10.
אז איך בולמים את זה?
אני לא היחיד שהבין שיש פה משהו בעייתי מבחינת פרטיות ויש כמה תוספים שמטפלים בזה – גם בכרום וגם בפיירפוקס. בכרום בדקתי את זה של SAGAN שהקוד שלו נמצא גם בגיטהאב והוא עובד. בפיירפוקס יש את התוסף הזה.
אבל להתקין תוספים כאלו, עם מעט משתמשים ותפוצה נמוכה יכול להיות ממש בעייתי מבחינת אבטחת מידע. אז אם יש לכם את tamper monkey (קישור לכרום וקישור לפיירפוקס), תוכלו להזריק את הסקריפט הבא:
window.addEventListener('visibilitychange', (e) => {
e.stopImmediatePropagation();
e.preventDefault();
}, true);
שימנע מאתרים לדעת מה אתם עושים.
אם אתם יודעים בוודאות שאתר מסוים עוקב אחריכם כך, אולי כדאי לשקול להשתמש בכרום עם התוסף ולהגביל אותו אך ורק לאתר שמבצע את המעקב. כרגע זה אפשרי רק בכרום.
לסיכום – מדובר על API מאוד שימושי אבל שיכול להיות הרסני לפרטיות של משתמשים. כך או כך, טוב לדעת ולהכיר.
6 תגובות
אולי שווה לציין שdocument.hidden נחשב מיושן ושיש היום את visibilityState
לאחרונה נוסף לכרום גם ה-IdleDetector API, שהוא הרבה יותר חזק מ-visibility כי הוא נשען על סיגנלים ממערכת ההפעלה ולא רק מהחלון הנוכחי, ובהתאם הוא שנוי במחלוקת משיקולי פרטיות ואבטחה. פתאום כל אתר יכול לדעת לא רק האם היוזר כרגע בחלון אלא באיזה שעות למשל היוזר לא נוגע במחשב, או האם ברבע שעה האחרונה הוא בכלל לא בסביבה (וזה זמן טוב להחליף את כל האתר בפישינג שמתחזה לבנק, לדוגמה).
כמובן שמהסיבות שהזכרת ועד לשיקולי ביצועים ועוד זה יכול להיות שימושי, אבל כן ייתכנו גם שימושים מטרידים ונראה שדפדפנים אחרים לא ימהרו לאמץ.
https://web.dev/idle-detection/
https://www.theregister.com/2021/09/22/google_emits_chrome_94_with/
התוסף או החתיכת קוד שמובאת באתר לא באמת חוסמת את הAPI, זה רק משנה מה קורה כשיש visibilitychange , לצורך העניין אתר שירצה להתחכם ולדעת אם המשתמש נמצא בעמוד יוכל לעשות זאת עם document.hidden, משו כמו
while (true) { await new Promise(r => setTimeout(r, 2000)); console.log(document.hidden)}
ידפיס כל 2 שניות אם המשתמש בעמוד או לא, האטריביוט hidden של document הוא read only ככה שאי אפשר לשנות אותו.
אשמח לשמוע אם באמת יש פתרון לדבר הזה
מוזמן לבדוק אותו ב-https://alligator.io/js/page-visibility-api/ ותראה שהוידאו נעצר. הדרך היותר טובה זה לתפוס את כל האיוונטים של visibilitychange, webkitvisibilitychange, blur ואז לתת להם true תמיד
דוגמה
for (event_name of ["visibilitychange", "webkitvisibilitychange", "blur"]) {
window.addEventListener(event_name, function(event) {
event.stopImmediatePropagation();
}, true);
ולא לשכוח לשים בmatch
*://*/*
שאלת תם.. בבואי לסגור טאב עם העכבר וקופץ לי חלון שמנסה לשכנע אותי להישאר, האם בזה הוא עושה שימוש או במשהו אחר?
יפה! השתמשתי לזה למטרות קצת פחות זדוניות – לחסוך בקריאות ajaax של עדכון הנתונים לחינם כאשר המשתמש בין כה לא צופה באתר…