การย้ายข้อมูลไปยังโหมด 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> ภายในส่วนหัวของหน้าเว็บที่ล้อมรอบอยู่

<!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 แทน

การส่งแบบฟอร์มไม่ได้ถูกป้องกันโดยค่าเริ่มต้นแล้ว

ภายใต้แบบฟอร์ม HTML แซนด์บ็อกซ์ของ NATIVE นั้นทำให้ส่งและไปยังส่วนต่างๆ ของหน้าเว็บไม่ได้ ด้วยเหตุนี้ นักพัฒนาแอปจึงสามารถเพิ่มแฮนเดิล 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 การสื่อสารแบบไคลเอ็นต์กับเซิร์ฟเวอร์