מעבר למצב IFRAME Sandbox

ב-Apps Script נעשה שימוש בארגז חול (Sandbox) לאבטחה כדי להגן על אפליקציות Google Workspaceבמצבים מסוימים. כל המצבים של ארגז חול נסגרים עכשיו, חוץ מ-IFRAME. אפליקציות שמשתמשות במצבי ארגז חול ישנים יותר משתמשות עכשיו באופן אוטומטי במצב IFRAME החדש יותר.

יכול להיות שאפליקציות שהשתמשו בעבר במצבים הישנים האלה עם שירות ה-HTML יצטרכו לבצע שינויים במצב IFRAME כדי לטפל בהבדלים הבאים:

  • עכשיו צריך לשנות את מאפיין target של הקישור באמצעות target="_top" או target="_blank"
  • קובצי HTML שמוצגים על ידי שירות ה-HTML חייבים לכלול את התגים <!DOCTYPE html> , <html> ו-<body>
  • ספריית הטוענים המקורית של Google api.js לא נטענת באופן אוטומטי במצב IFRAME
  • משתמשי הבורר צריכים לשלוח קריאה ל- setOrigin() מפני שהתוכן מוצג מדומיין חדש
  • חלק מהדפדפנים הישנים, כולל IE9, אינם נתמכים
  • משאבים מיובאים חייבים עכשיו להשתמש ב-HTTPS
  • כברירת מחדל, כבר לא ניתן למנוע שליחה של טפסים

ההבדלים האלה מפורטים בקטעים הבאים.

במצב IFRAME, צריך להגדיר את מאפיין יעד הקישור כ-_top או כ-_blank:

Code.js

function doGet() {
  var template = HtmlService.createTemplateFromFile('top');
  return template.evaluate();
}

top.html

<!DOCTYPE html>
<html>
 <body>
   <div>
     <a href="http://google.com" target="_top">Click Me!</a>
   </div>
 </body>
</html>

אפשר לשנות את המאפיין הזה גם באמצעות התג <base> בתוך קטע ה-head בדף האינטרנט שמצורף:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
   <div>
     <a href="http://google.com">Click Me!</a>
   </div>
 </body>
</html>

תגי HTML ברמה העליונה

במצב ארגז חול NATIVE (ו-EMULATED), תגי HTML מסוימים יתווספו אוטומטית לקובץ .html של Apps Script, אבל זה לא יקרה כשמשתמשים במצב IFRAME.

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

<!DOCTYPE html>
<html>
  <body>
    <!-- Add your HTML content here -->
  </body>
</html>

יש לטעון באופן מפורש את ספריית הטעינה המקורית של JavaScript

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

<script src="https://apis.google.com/js/api.js?onload=onApiLoad">
</script>

שינוי ב-Google Picker API

כשמשתמשים ב-Google Picker API, צריך לקרוא ל-setOrigin() כשבונים את PickerBuilder ולהעביר אותו במקור google.script.host.origin, כמו בדוגמה הבאה:

function createPicker(oauthToken) {
  var picker = new google.picker.PickerBuilder()
      .addView(google.picker.ViewId.SPREADSHEETS) // Or a different ViewId
      .setOAuthToken(oauthToken)
      .setDeveloperKey(developerKey)
      .setCallback(pickerCallback)
      .setOrigin(google.script.host.origin) // Note the setOrigin
      .build();
  picker.setVisible(true);
}

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

תמיכת דפדפן

מצב ה-Sandbox IFRAME מבוסס על התכונה הרצה בארגז חול (sandboxing) ב-iframe ב-HTML5. בדפדפנים ישנים יותר, כמו Internet Explorer 9, אי אפשר לעשות את זה. זו יכולה להיות בעיה אם בפרויקט Apps Script שלכם:

  • משתמש ב-HtmlService,
  • נעשה שימוש בעבר בארגז חול (sandboxing) של EMULATED או NATIVE

המשמעות של העברת האפליקציות האלה למצב ארגז חול של IFRAME היא שיכול להיות שהן לא יפעלו יותר בכמה דפדפנים ישנים (במיוחד ב-IE9 ובגרסאות קודמות) שלא תומכים בתכונה'ארגז חול (sandboxing)' של HTML5 ב-HTML5.

אפליקציות שכבר מבקשות את מצב IFRAME או שלא משתמשות ב-HtmlService בכלל לא מושפעות מהבעיה הזו.

עכשיו נדרש HTTPS למשאבים מיובאים

אם יש אפליקציות קודמות שיובאו משאבים באמצעות HTTP, צריך לשנות אותן כך שישתמשו ב-HTTPS במקום זאת.

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

לא ניתן היה לשלוח את הדף ולנווט בו באמצעות הרצה בארגז חול (sandboxing) של טופסי HTML ב-NATIVE. לכן, המפתח יכול פשוט להוסיף handler של onclick ללחצן השליחה, בלי לדאוג מה קרה.

עם זאת, במצב IFRAME אפשר לשלוח טופסי HTML. אם לרכיב הטופס לא צוין מאפיין action, הוא יישלח לדף ריק. אחרת, ה-iframe הפנימי יפנה לדף הריק לפני שתהיה ל-handler של onclick אפשרות לסיים.

הפתרון הוא להוסיף קוד JavaScript לדף שמונע את השליחה של רכיבי הטופס בפועל, כדי שלרכיבי ה-handler של הקליקים יהיה זמן לפעול:

<script>
  // Prevent forms from submitting.
  function preventFormSubmit() {
    var forms = document.querySelectorAll('form');
    for (var i = 0; i < forms.length; i++) {
      forms[i].addEventListener('submit', function(event) {
        event.preventDefault();
      });
    }
  }
  window.addEventListener('load', preventFormSubmit);
</script>

דוגמה מלאה אפשר למצוא במדריך HtmlService בתקשורת בין לקוח לשרת.