מעבר למצב IFRAME Sandbox

Apps Script משתמש בארגז חול של אבטחה כדי לספק בידוד לאפליקציות 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 מקורית של טוען 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 בעבר

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

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

מעכשיו צריך להשתמש ב-HTTPS למשאבים מיובאים

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

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

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

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

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

<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, Client-to-Server Communication.