Apps Script ใช้แซนด์บ็อกซ์ด้านความปลอดภัย
เพื่อแยกแอปพลิเคชัน Google Workspace
ในบางสถานการณ์เพื่อการปกป้อง ตอนนี้เราได้หยุดให้บริการโหมดแซนด์บ็อกซ์ทั้งหมดแล้ว ยกเว้น IFRAME แอปที่ใช้ Sandbox
โหมดเก่าจะใช้โหมด 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> ภายในส่วนหัว ของหน้าเว็บที่ครอบคลุม
<!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);
}
ดูตัวอย่างการทำงานทั้งหมดได้ที่กล่องโต้ตอบการเปิดไฟล์
การสนับสนุนเบราว์เซอร์
IFRAMEโหมดแซนด์บ็อกซ์อิงตามฟีเจอร์แซนด์บ็อกซ์ iframe
ใน HTML5
เบราว์เซอร์รุ่นเก่าบางรุ่น เช่น Internet Explorer 9 ไม่รองรับฟีเจอร์นี้ ซึ่งอาจเป็นปัญหาหากโปรเจ็กต์ Apps Script ของคุณมีลักษณะดังนี้
- ใช้ 
HtmlServiceและ EMULATEDหรือNATIVEแซนด์บ็อกซ์ที่ใช้ก่อนหน้านี้
การย้ายข้อมูลแอปเหล่านี้ไปยังIFRAMEโหมดแซนด์บ็อกซ์หมายความว่าแอปอาจใช้ไม่ได้อีกต่อไปใน
เบราว์เซอร์รุ่นเก่าบางรุ่น (โดยเฉพาะ IE9 และรุ่นก่อนหน้า) ที่ไม่รองรับฟีเจอร์แซนด์บ็อกซ์ iframe ของ HTML5
แอปที่ขอโหมด IFRAME อยู่แล้วหรือไม่ได้ใช้ HtmlService เลยจะไม่ได้รับผลกระทบจากปัญหานี้
ตอนนี้ต้องใช้ HTTPS สำหรับทรัพยากรที่นำเข้า
แอปพลิเคชันก่อนหน้านี้ที่นำเข้าทรัพยากรโดยใช้ HTTP ต้องเปลี่ยนไปใช้ HTTPS แทน
ระบบจะไม่ป้องกันการส่งแบบฟอร์มโดยค่าเริ่มต้นอีกต่อไป
ในส่วนNATIVE การแซนด์บ็อกซ์จะป้องกันไม่ให้แบบฟอร์ม HTML ส่งจริง
และไปยังหน้าเว็บ ด้วยเหตุนี้ นักพัฒนาแอปจึงเพียงแค่เพิ่มonclick
แฮนเดิลเลอร์ลงในปุ่มส่งและไม่ต้องกังวลว่าจะเกิดอะไรขึ้นหลังจากนั้น
แต่ในIFRAMEโหมดจะอนุญาตให้ส่งแบบฟอร์ม HTML และหากองค์ประกอบแบบฟอร์มไม่มีการระบุแอตทริบิวต์ action ระบบจะส่งไปยังหน้าว่าง
ที่แย่กว่านั้นคือ iframe ด้านในจะเปลี่ยนเส้นทางไปยังหน้าว่างก่อนที่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 การสื่อสารจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์