Treści zewnętrzne

Model zabezpieczeń aplikacji Chrome nie zezwala na umieszczanie treści zewnętrznych w elementach iframe ani korzystanie z wbudowanych skryptów oraz eval(). Możesz obejść te ograniczenia, ale treści zewnętrzne muszą być odizolowane od aplikacji.

Izolowane treści nie mają bezpośredniego dostępu do danych aplikacji ani interfejsów API. Używaj żądań XMLHttpRequest z innych domen i post-messa do komunikacji między stroną zdarzenia a treścią w piaskownicy oraz pośrednio uzyskiwać dostęp do interfejsów API.

Odwoływanie się do zasobów zewnętrznych

Polityka bezpieczeństwa treści używana przez aplikacje nie zezwala na korzystanie z wielu rodzajów zdalnych adresów URL, więc na stronie aplikacji nie możesz odwoływać się bezpośrednio do zewnętrznych obrazów, arkuszy stylów ani czcionek. Zamiast tego możesz pobierać te zasoby za pomocą żądań XMLHttpRequest z innych domen, a potem wyświetlać je za pomocą adresów URL blob:.

Wymagania dotyczące pliku manifestu

Aby móc wysyłać żądania XMLHttpRequest z innych domen, musisz dodać uprawnienie dla hosta zdalnego adresu URL:

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

Międzyźródłowe żądanie XMLHttpRequest

Pobierz zdalny adres URL do aplikacji i wyświetlaj jego zawartość jako 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();

Warto zapisać te zasoby lokalnie, aby były dostępne offline.

Umieszczanie zewnętrznych stron internetowych

Tag webview umożliwia umieszczanie w aplikacji zewnętrznych treści internetowych, np. strony internetowej. Zastępuje elementy iframe wskazujące zdalne adresy URL, które są wyłączone w aplikacjach Chrome. W przeciwieństwie do elementów iframe tag webview działa w osobnym procesie. Oznacza to, że wykorzystywany w nim luka w dalszym ciągu będzie odizolowany i nie będzie mógł uzyskać podwyższonych przywilejów. Poza tym pamięć (pliki cookie itp.) jest oddzielona od aplikacji, więc treści internetowe nie mają dostępu do żadnych danych aplikacji.

Dodaj element WebView

Element webview musi zawierać adres URL treści źródłowej i określać jej wymiary.

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

Aktualizowanie właściwości

Aby dynamicznie zmieniać właściwości src, width i height tagu webview, możesz ustawić je bezpośrednio w obiekcie JavaScriptu lub użyć funkcji setAttribute DOM.

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

Treści lokalne w piaskownicy

Piaskownica umożliwia wyświetlanie określonych stron w unikalnym źródle, który znajduje się w trybie piaskownicy. Takie strony są następnie zwolnione z obowiązku przestrzegania standardu Content Security Policy. Strony w trybie piaskownicy mogą korzystać z elementów iframe, wbudowanego skryptu i elementu eval(). Sprawdź opis pola manifestu w przypadku sandbox.

Natrafia na to jednak: strony w piaskownicy nie mogą używać Chrome*. Interfejsy API. Jeśli musisz zrobić coś takiego jak eval(), wybierz tę trasę, aby zostać zwolnionym z obowiązku posiadania licencji CSP, ale nie będziesz mieć możliwości korzystania z nowych, ciekawych funkcji.

Używaj skryptów wbudowanych w piaskownicy

Oto przykładowa strona w trybie piaskownicy, która korzysta z wbudowanego skryptu i elementu eval():

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

Dodaj piaskownicę do pliku manifestu

Musisz dodać do pliku manifestu pole sandbox i wpisać listę stron aplikacji, które mają być wyświetlane w piaskownicy:

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

Otwieranie strony w trybie piaskownicy w oknie

Tak jak w przypadku każdej innej strony aplikacji, możesz utworzyć okno, w którym będzie się otwierać strona w trybie piaskownicy. Oto przykład tworzenia 2 okien – głównego okna aplikacji poza piaskownicą, a drugiego dla strony w piaskownicy:

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

Umieszczanie na stronie aplikacji strony w trybie piaskownicy

Strony w trybie piaskownicy można też umieścić na innej stronie aplikacji za pomocą elementu 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>

Wysyłanie wiadomości do stron w trybie piaskownicy

Wysłanie wiadomości składa się z 2 etapów: opublikowania wiadomości ze strony lub okna nadawcy i odsłuchania wiadomości na stronie lub w oknie docelowym.

Opublikuj wiadomość

Za pomocą postMessage możesz komunikować się między aplikacją a treścią w piaskownicy. Oto przykładowy skrypt działający w tle, który publikuje wiadomość na otwartej stronie piaskownicy:

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

Ogólnie rzecz biorąc, w internecie chcesz dokładnie określić, skąd jest wysyłana wiadomość. Aplikacje Chrome nie mają dostępu do unikalnego źródła treści w trybie piaskownicy, więc możesz dodać wszystkie źródła do listy dozwolonych („*”) jako akceptowane źródła. Po stronie odbierającej zwykle warto sprawdzić źródło, ale nie jest to konieczne, ponieważ treść aplikacji Chrome jest w nim zawarta. Więcej informacji znajdziesz tutaj: window.postMessage.

Słuchaj wiadomości i odpowiedzi

Oto przykładowy odbiornik wiadomości, który zostanie dodany do strony piaskownicy:

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

Więcej informacji znajdziesz w przykładzie dotyczącym sandbox.