เนื้อหาภายนอก

โมเดลความปลอดภัยของแอป 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 แท็ก webview ทำงานในกระบวนการที่แยกต่างหาก ซึ่งต่างจาก iframe ซึ่งหมายความว่าการเจาะช่องโหว่ภายในเนื้อหาดังกล่าวจะยังคงถูกแยกออก และจะไม่ได้รับสิทธิ์ในระดับสูงขึ้น นอกจากนี้ เนื่องจากพื้นที่เก็บข้อมูล (คุกกี้ ฯลฯ) จะแยกออกจากแอป เนื้อหาเว็บจะไม่สามารถเข้าถึงข้อมูลของแอปได้

เพิ่มองค์ประกอบ WebView

องค์ประกอบ webview ต้องมี URL ไปยังเนื้อหาแหล่งที่มาและระบุขนาด

<webview src="http://news.google.com/" width="640" height="480"></webview>

อัปเดตที่พัก

หากต้องการเปลี่ยนพร็อพเพอร์ตี้ src, width และ height ของแท็ก webview แบบไดนามิก คุณจะตั้งค่าพร็อพเพอร์ตี้เหล่านั้นโดยตรงในออบเจ็กต์ JavaScript หรือใช้ฟังก์ชัน setAttribute DOM ก็ได้

document.querySelector('#mywebview').src =
    'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
    'src', 'http://blog.chromium.org/');

เนื้อหาในเครื่องแซนด์บ็อกซ์

แซนด์บ็อกซ์ช่วยให้หน้าที่ระบุแสดงในต้นทางที่ไม่ซ้ำกันและมีแซนด์บ็อกซ์ จากนั้นหน้าเหล่านี้จะได้รับการยกเว้นจากนโยบายรักษาความปลอดภัยเนื้อหา หน้าแซนด์บ็อกซ์จะใช้ iframe, การเขียนสคริปต์ในหน้า และ eval() ได้ ดูคำอธิบายช่องไฟล์ Manifest ของ sandbox

แต่ข้อดีข้อเสียก็คือ หน้าที่ทำแซนด์บ็อกซ์จะใช้ 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);

ดูรายละเอียดเพิ่มเติมได้ในตัวอย่างsandbox