Externer Inhalt

Das Chrome-Apps-Sicherheitsmodell verbietet externe Inhalte in iFrames sowie die Verwendung von Inline-Skripts und eval(). Sie können diese Einschränkungen überschreiben, aber Ihre externen Inhalte müssen von der Anwendung isoliert sein.

Isolierte Inhalte können nicht direkt auf die Daten der App oder auf eine der APIs zugreifen. Verwende ursprungsübergreifende XMLHttpRequests und Post-Messaging, um zwischen der Ereignisseite und den in der Sandbox ausgeführten Inhalten zu kommunizieren und indirekt auf die APIs zuzugreifen.

Auf externe Ressourcen verweisen

Die von Apps verwendete Content Security Policy unterbindet die Verwendung vieler Arten von Remote-URLs, sodass Sie auf einer App-Seite nicht direkt auf externe Bilder, Stylesheets oder Schriftarten verweisen können. Stattdessen kannst du diese Ressourcen mit ursprungsübergreifenden XMLHttpRequests abrufen und sie dann über blob:-URLs bereitstellen.

Manifestanforderung

Um ursprungsübergreifende XMLHttpRequests ausführen zu können, musst du eine Berechtigung für den Host der Remote-URL hinzufügen:

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

Ursprungsübergreifender XMLHttpRequest

Rufen Sie die Remote-URL in der App ab und stellen Sie deren Inhalt als blob:-URL bereit:

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

Sie können diese Ressourcen lokal speichern, damit sie offline verfügbar sind.

Externe Webseiten einbetten

Mit dem Tag webview können Sie externe Webinhalte in Ihre App einbetten, z. B. eine Webseite. Sie ersetzt iFrames, die auf Remote-URLs verweisen, die in Chrome-Apps deaktiviert sind. Im Gegensatz zu iFrames wird das webview-Tag in einem separaten Prozess ausgeführt. Das bedeutet, dass ein Exploit darin weiterhin isoliert ist und keine erhöhten Berechtigungen erlangen kann. Da der Speicher (Cookies usw.) von der App isoliert ist, haben die Webinhalte keine Möglichkeit, auf die App-Daten zuzugreifen.

WebView-Element hinzufügen

Das webview-Element muss die URL zum Quellcontent enthalten und seine Abmessungen angeben.

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

Unterkünfte aktualisieren

Wenn Sie die Eigenschaften src, width und height eines webview-Tags dynamisch ändern möchten, können Sie diese Eigenschaften entweder direkt im JavaScript-Objekt festlegen oder die DOM-Funktion setAttribute verwenden.

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

Sandbox für lokale Inhalte

Durch die Sandboxing-Technologie können bestimmte Seiten in einer Sandbox-Umgebung, die auf einer eindeutigen Quelle basiert, bereitgestellt werden. Diese Seiten sind dann von ihrer Content Security Policy ausgenommen. Für in einer Sandbox ausgeführte Seiten können iFrames, Inline-Scripting und eval() verwendet werden. Sehen Sie sich die Beschreibung des Manifestfelds für sandbox an.

Ein Nachteil ist: Seiten, die in einer Sandbox ausgeführt werden, können Chrome nicht verwenden.* APIs Wenn du Dinge wie eval() ausführen musst, begib dich auf diese Route, um von der CSP ausgenommen zu werden, aber du kannst die coolen neuen Funktionen nicht verwenden.

Inline-Skripts in der Sandbox verwenden

Hier ist eine Beispielseite, die in einer Sandbox ausgeführt wird und ein Inline-Skript und eval() verwendet:

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

Sandbox in Manifest einschließen

Du musst das Feld sandbox in das Manifest einfügen und die App-Seiten auflisten, die in einer Sandbox bereitgestellt werden sollen:

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

Sandbox-Seite in einem Fenster öffnen

Wie bei allen anderen App-Seiten können Sie ein Fenster erstellen, in dem die Sandbox-Seite geöffnet wird. Im folgenden Beispiel werden zwei Fenster erstellt: eines für das Hauptfenster der App, das sich nicht in einer Sandbox befindet, und eines für die Seite, die in einer Sandbox ausgeführt wird:

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

Sandbox-Seite in eine App-Seite einbetten

In einer Sandbox ausgeführte Seiten können mithilfe von iframe auch in eine andere App-Seite eingebettet werden:

<!DOCTYPE html>
<html>
<head>
</head>
  <body>
    <p>I am normal app window.</p>

    <iframe src="sandboxed.html" width="300" height="200"></iframe>
  </body>
</html>

Nachrichten an Seiten senden, die in einer Sandbox ausgeführt werden

Das Senden einer Nachricht erfolgt in zwei Schritten: Sie müssen eine Nachricht von der Absenderseite bzw. dem Absenderfenster posten und auf der empfangenden Seite bzw. dem Empfängerfenster warten.

Nachricht posten

Du kannst postMessage für die Kommunikation zwischen deiner App und Sandbox-Inhalten verwenden. Hier sehen Sie ein Beispielskript für den Hintergrund, das eine Nachricht an die in der Sandbox ausgeführte Seite postet:

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

Im Allgemeinen sollten Sie im Web den genauen Ursprung angeben, von dem die Nachricht gesendet wird. Chrome-Apps haben keinen Zugriff auf den eindeutigen Ursprung von Sandbox-Inhalten. Sie können daher nur alle Quellen als zulässige Ursprünge ('*') auf die Zulassungsliste setzen. Am Empfänger sollten Sie in der Regel den Ursprung überprüfen. Da Chrome-Apps-Inhalte jedoch enthalten sind, ist dies nicht erforderlich. Weitere Informationen finden Sie unter window.postMessage.

Auf Nachricht warten und antworten

Hier ein Beispiel für einen Nachrichtenempfänger, der Ihrer Sandbox-Seite hinzugefügt wird:

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

Weitere Informationen erhalten Sie im sandbox.