מעבר למצב 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
  • משתמשי Picker צריכים לבצע קריאה ל-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) ב-sandbox, תגי HTML מסוימים יתווספו באופן אוטומטי לקובץ ‎ .html של Apps Script, אבל זה לא קורה כשמשתמשים במצב IFRAME.

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

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

צריך לטעון את ספריית ה-loader של 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);
}

דוגמה מלאה שפועלת מופיעה במאמר תיבות דו-שיח לפתיחת קובץ.

תמיכה בדפדפנים

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

  • משתמש ב-HtmlService, וגם
  • שימוש קודם ב-EMULATED או ב-NATIVE ב-sandbox

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

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

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

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

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

במסגרת NATIVE, טופס HTML ב-sandboxing לא הצליח לשלוח את הנתונים ולנווט בדף. לכן, מפתח יכול פשוט להוסיף טיפול 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 תקשורת מלקוח לשרת.