מעבר למצב 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> תג בתוך הראש בקטע של דף האינטרנט המצורף:

<!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 וה-pass ב-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 ודגמים קודמים) שאינם תומכים ב-iframe של HTML5 הרצה בארגז חול (sandboxing).

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

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

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

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

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

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

הפתרון הוא להוסיף קוד 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 תקשורת בין לקוח לשרת.