Konten Eksternal

Model keamanan Aplikasi Chrome tidak mengizinkan konten eksternal dalam iframe serta penggunaan skrip inline dan eval(). Anda dapat mengganti batasan ini, tetapi konten eksternal Anda harus diisolasi dari aplikasi.

Konten yang diisolasi tidak dapat langsung mengakses data aplikasi atau API apa pun. Gunakan XMLHttpRequests lintas origin dan pasca-pesan untuk berkomunikasi antara halaman peristiwa dan konten dalam sandbox serta mengakses API secara tidak langsung.

Mereferensikan referensi eksternal

Kebijakan Keamanan Konten yang digunakan oleh aplikasi tidak mengizinkan penggunaan berbagai jenis URL jarak jauh, sehingga Anda tidak dapat langsung mereferensikan gambar eksternal, stylesheet, atau font dari halaman aplikasi. Sebagai gantinya, Anda dapat menggunakan XMLHttpRequests lintas origin untuk mengambil resource ini, lalu menayangkannya melalui URL blob:.

Persyaratan manifes

Agar dapat melakukan XMLHttpRequests lintas origin, Anda harus menambahkan izin untuk host URL jarak jauh:

"permissions": [
    "...",
    "https://supersweetdomainbutnotcspfriendly.com/"
  ]

XMLHttpRequest lintas origin

Ambil URL jarak jauh ke dalam aplikasi dan tayangkan kontennya sebagai 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();

Sebaiknya simpan resource ini secara lokal agar tersedia secara offline.

Menyematkan halaman web eksternal

Tag webview memungkinkan Anda menyematkan konten web eksternal di aplikasi, misalnya halaman web. Kebijakan ini menggantikan iframe yang mengarah ke URL jarak jauh, yang dinonaktifkan di dalam Aplikasi Chrome. Tidak seperti iframe, tag webview berjalan dalam proses terpisah. Artinya, eksploit di dalamnya akan tetap terisolasi dan tidak akan dapat memperoleh hak istimewa yang ditingkatkan. Selain itu, karena penyimpanannya (cookie, dll.) terisolasi dari aplikasi, tidak ada cara bagi konten web untuk mengakses data aplikasi apa pun.

Tambahkan elemen webview

Elemen webview Anda harus menyertakan URL ke konten sumber dan menentukan dimensinya.

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

Perbarui properti

Untuk mengubah properti src, width, dan height secara dinamis pada tag webview, Anda dapat menetapkan properti tersebut langsung di objek JavaScript, atau menggunakan fungsi DOM setAttribute.

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

Konten lokal sandbox

Dengan sandbox, halaman tertentu dapat ditayangkan di origin yang unik dan dalam sandbox. Halaman ini kemudian dikecualikan dari Kebijakan Keamanan Konten. Halaman dengan sandbox dapat menggunakan iframe, pembuatan skrip inline, dan eval(). Lihat deskripsi kolom manifes untuk sandbox.

Namun ini adalah konsekuensinya: halaman dengan sandbox tidak dapat menggunakan Chrome.* API. Jika Anda perlu melakukan hal-hal seperti eval(), buka rute ini untuk dikecualikan dari CSP, tetapi Anda tidak akan dapat menggunakan hal-hal baru yang keren.

Menggunakan skrip inline di sandbox

Berikut ini contoh halaman dalam sandbox yang menggunakan skrip inline dan eval():

<html>
  <body>
    <h1>Woot</h1>
    <script>
      eval('console.log(\'I am an eval-ed inline script.\')');
    </script>
  </body>
</html>

Menyertakan sandbox dalam manifes

Anda harus menyertakan kolom sandbox dalam manifes dan mencantumkan halaman aplikasi yang akan disalurkan di sandbox:

"sandbox": {
  "pages": ["sandboxed.html"]
}

Membuka halaman dalam sandbox di jendela

Sama seperti halaman aplikasi lainnya, Anda dapat membuat jendela tempat halaman dalam sandbox terbuka. Berikut ini contoh yang membuat dua jendela, satu untuk jendela aplikasi utama yang tidak di-sandbox, dan satu untuk halaman dengan sandbox:

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
    }
  });
});

Menyematkan halaman dalam sandbox di halaman aplikasi

Halaman dengan sandbox juga dapat disematkan di dalam halaman aplikasi lain menggunakan 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>

Mengirim pesan ke halaman dalam sandbox

Ada dua bagian dalam mengirim pesan: Anda harus memposting pesan dari halaman/jendela pengirim, dan memproses pesan di halaman/jendela penerima.

Posting pesan

Anda dapat menggunakan postMessage untuk berkomunikasi antara aplikasi Anda dan konten dalam sandbox. Berikut ini contoh skrip latar belakang yang memposting pesan ke halaman dalam sandbox yang dibukanya:

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.', '*');
     });
});

Secara umum di web, Anda ingin menentukan asal yang tepat dari tempat pesan dikirim. Aplikasi Chrome tidak memiliki akses ke asal unik konten yang di-sandbox, sehingga Anda hanya dapat mengizinkan semua origin sebagai origin yang dapat diterima ('*'). Di sisi penerima, Anda biasanya ingin memeriksa originnya; tetapi karena konten Aplikasi Chrome terdapat, hal ini tidak perlu. Untuk mengetahui lebih lanjut, lihat window.postMessage.

Mendengarkan pesan dan membalas

Berikut adalah contoh penerima pesan yang ditambahkan ke halaman dalam sandbox:

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);

Untuk detail selengkapnya, lihat contoh sandbox.