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 การสื่อสารจากไคลเอ็นต์ไปยังเซิร์ฟเวอร์