โมเดลความปลอดภัยของแอป Chrome ไม่อนุญาตเนื้อหาภายนอกใน iframe และใช้อินไลน์
และ eval()
คุณลบล้างข้อจำกัดเหล่านี้ได้ แต่เนื้อหาภายนอกจะต้อง
แยกต่างหากจากแอป
เนื้อหาที่แยกไว้ไม่สามารถเข้าถึงข้อมูลของแอปหรือ API ใดๆ ได้โดยตรง ใช้ข้ามต้นทาง XMLHttpRequests และการโพสต์ข้อความเพื่อสื่อสารระหว่างหน้ากิจกรรมและเนื้อหาที่ถูกแซนด์บ็อกซ์ และ เข้าถึง API ได้ทางอ้อม
การอ้างอิงทรัพยากรภายนอก
นโยบายรักษาความปลอดภัยเนื้อหาที่แอปใช้ไม่อนุญาตให้ใช้ URL ระยะไกลหลายประเภท ดังนั้น
อ้างอิงรูปภาพภายนอก สไตล์ชีต หรือแบบอักษรจากหน้าแอปโดยตรงไม่ได้ อย่างไรก็ตาม คุณสามารถ
ใช้ XMLHttpRequests แบบข้ามต้นทางเพื่อดึงข้อมูลทรัพยากรเหล่านี้ แล้วแสดงผลผ่าน URL blob:
ข้อกำหนดของไฟล์ Manifest
เพื่อให้สามารถสร้าง XMLHttpRequests แบบข้ามต้นทางได้ คุณจะต้องเพิ่มสิทธิ์สำหรับ URL ระยะไกล เจ้าภาพ:
"permissions": [
"...",
"https://supersweetdomainbutnotcspfriendly.com/"
]
XMLHttpRequest แบบข้ามต้นทาง
ดึงข้อมูล URL ระยะไกลลงในแอปและแสดงเนื้อหาเป็น URL blob:
:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://supersweetdomainbutnotcspfriendly.com/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(this.response);
document.body.appendChild(img);
};
xhr.send();
คุณอาจต้องการบันทึกทรัพยากรเหล่านี้ไว้ในเครื่อง เพื่อให้ใช้งานแบบออฟไลน์ได้
ฝังหน้าเว็บภายนอก
แท็ก webview
ช่วยให้คุณฝังเนื้อหาเว็บภายนอกในแอปได้ เช่น เว็บ
โดยจะแทนที่ iframe ที่ชี้ไปยัง URL ระยะไกลซึ่งถูกปิดใช้ภายในแอป Chrome เลิกชอบ
iframe แท็ก webview
จะทำงานในกระบวนการที่แยกต่างหาก ซึ่งหมายความว่าการเจาะช่องโหว่ภายในจะ
คุณจะยังคงโดดเดี่ยวและไม่สามารถรับสิทธิพิเศษในระดับสูงขึ้นได้ เพิ่มเติม เนื่องจากพื้นที่เก็บข้อมูล
(คุกกี้ ฯลฯ) จะถูกแยกออกมาจากแอป ไม่มีทางที่เนื้อหาเว็บจะเข้าถึง
ข้อมูลของแอป
เพิ่มองค์ประกอบ WebView
องค์ประกอบ webview
ต้องมี URL ไปยังเนื้อหาแหล่งที่มาและระบุมิติข้อมูล
<webview src="http://news.google.com/" width="640" height="480"></webview>
อัปเดตที่พัก
หากต้องการเปลี่ยนพร็อพเพอร์ตี้ src
, width
และ height
ของแท็ก webview
แบบไดนามิก ให้ทำดังนี้
ให้ตั้งค่าคุณสมบัติเหล่านั้นในออบเจ็กต์ JavaScript โดยตรงหรือใช้ฟังก์ชัน DOM ของ setAttribute
document.querySelector('#mywebview').src =
'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
'src', 'http://blog.chromium.org/');
เนื้อหาในเครื่องของแซนด์บ็อกซ์
แซนด์บ็อกซ์ช่วยให้แสดงหน้าที่ระบุในต้นทางที่ไม่ซ้ำและแซนด์บ็อกซ์ได้ หน้าเว็บเหล่านี้จะ
ได้รับการยกเว้นจากนโยบายรักษาความปลอดภัยเนื้อหา หน้าที่แซนด์บ็อกซ์สามารถใช้ iframe, การเขียนสคริปต์ในหน้า และ
eval()
ดูคำอธิบายช่องไฟล์ Manifest สำหรับแซนด์บ็อกซ์
แต่ทั้งนี้ก็ต้องแลกกันเพราะหน้าเว็บที่แซนด์บ็อกซ์ไว้จะใช้ Chrome ไม่ได้* API หากคุณจำเป็นต้องทำสิ่งต่างๆ เช่น
eval()
ไปที่เส้นทางนี้เพื่อได้รับการยกเว้นจาก CSP แต่คุณจะไม่สามารถใช้สิ่งใหม่ๆ ที่น่าสนใจได้
ใช้สคริปต์ในหน้าในแซนด์บ็อกซ์
นี่คือตัวอย่างหน้าแซนด์บ็อกซ์ที่ใช้สคริปต์ในหน้าและ eval()
<html>
<body>
<h1>Woot</h1>
<script>
eval('console.log(\'I am an eval-ed inline script.\')');
</script>
</body>
</html>
รวมแซนด์บ็อกซ์ในไฟล์ Manifest
คุณต้องรวมช่อง sandbox
ในไฟล์ Manifest และแสดงรายการหน้าแอปที่จะแสดงใน
แซนด์บ็อกซ์:
"sandbox": {
"pages": ["sandboxed.html"]
}
การเปิดหน้าเว็บที่แซนด์บ็อกซ์ในหน้าต่าง
เช่นเดียวกับหน้าแอปอื่นๆ คุณสามารถสร้างหน้าต่างซึ่งหน้าแซนด์บ็อกซ์นั้นจะเปิดขึ้น ต่อไปนี้คือ ตัวอย่างที่สร้าง 2 หน้าต่าง หน้าต่างหนึ่งสำหรับหน้าต่างแอปหลักที่ไม่ใช่แซนด์บ็อกซ์ และอีกหน้าต่างหนึ่งสำหรับ หน้าเว็บที่ใช้แซนด์บ็อกซ์:
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('window.html', {
'bounds': {
'width': 400,
'height': 400,
'left': 0,
'top': 0
}
});
chrome.app.window.create('sandboxed.html', {
'bounds': {
'width': 400,
'height': 400,
'left': 400,
'top': 0
}
});
});
การฝังหน้าแซนด์บ็อกซ์ในหน้าแอป
คุณยังฝังหน้าแซนด์บ็อกซ์ในหน้าแอปอื่นได้โดยใช้ iframe
:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>I am normal app window.</p>
<iframe src="sandboxed.html" width="300" height="200"></iframe>
</body>
</html>
การส่งข้อความไปยังหน้าแซนด์บ็อกซ์
การส่งข้อความแบ่งออกเป็น 2 ส่วน ได้แก่ การโพสต์ข้อความจากหน้า/หน้าต่างผู้ส่ง และฟังข้อความในหน้า/หน้าต่างรับข้อมูล
โพสต์ข้อความ
คุณใช้ postMessage
เพื่อสื่อสารระหว่างแอปของคุณกับเนื้อหาที่อยู่ในแซนด์บ็อกซ์ได้ นี่คือตัวอย่าง
สคริปต์พื้นหลังที่โพสต์ข้อความไปยังหน้าแซนด์บ็อกซ์ ข้อความจะเปิดขึ้น:
var myWin = null;
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('sandboxed.html', {
'bounds': {
'width': 400,
'height': 400
}
}, function(win) {
myWin = win;
myWin.contentWindow.postMessage('Just wanted to say hey.', '*');
});
});
โดยทั่วไปบนเว็บ คุณจะทราบต้นทางที่เจาะจงของที่ส่งข้อความ แอป Chrome ไม่มีสิทธิ์เข้าถึงต้นทางที่ไม่ซ้ำกันของเนื้อหาที่ทำแซนด์บ็อกซ์ ดังนั้นคุณจะอนุญาตได้เฉพาะเนื้อหาทั้งหมด เป็นต้นทางที่ยอมรับได้ ("*") โดยทั่วไปแล้ว คุณจะต้องตรวจสอบต้นทางที่ฝั่งผู้รับ แต่เพราะมีเนื้อหาแอป Chrome อยู่ด้วย จึงไม่จำเป็นต้องดำเนินการ อ่านเพิ่มเติมได้ที่ window.postMessage.
ฟังข้อความและตอบกลับ
ต่อไปนี้คือตัวอย่างตัวรับข้อความที่เพิ่มลงในหน้าแซนด์บ็อกซ์ของคุณ
var messageHandler = function(event) {
console.log('Background script says hello.', event.data);
// Send a reply
event.source.postMessage(
{'reply': 'Sandbox received: ' + event.data}, event.origin);
};
window.addEventListener('message', messageHandler);
ดูรายละเอียดเพิ่มเติมได้ในตัวอย่างแซนด์บ็อกซ์