การย้ายข้อมูลไปยังโหมด IFRAME Sandbox

Apps Script ใช้ แซนด์บ็อกซ์ความปลอดภัยเพื่อแยกแอปพลิเคชัน ออกจากระบบในบางสถานการณ์ เราหยุดให้บริการโหมดแซนด์บ็อกซ์ทั้งหมดแล้ว ยกเว้น 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 อยู่แล้วหรือไม่ใช้ 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 การสื่อสารจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์