Contenuti esterni

Il modello di sicurezza delle app di Chrome non consente i contenuti esterni negli iframe e l'utilizzo di e eval(). Puoi ignorare queste restrizioni, ma i tuoi contenuti esterni devono essere isolato dall'app.

I contenuti isolati non possono accedere direttamente ai dati dell'app o a nessuna delle API. Utilizza multiorigine XMLHttpRequests e post-messaggistica per la comunicazione tra la pagina dell'evento e i contenuti con sandbox e accedere indirettamente alle API.

Fare riferimento a risorse esterne

Il Criterio di sicurezza del contenuto usato dalle app non consente l'utilizzo di molti tipi di URL remoti, quindi non possono fare riferimento direttamente a immagini, fogli di stile o caratteri esterni dalla pagina di un'app. Puoi invece utilizza XMLHttpRequests multiorigine per recuperare queste risorse e poi pubblicarle tramite URL blob:.

Requisito del file manifest

Per poter eseguire XMLHttpRequests multiorigine, devi aggiungere un'autorizzazione per l'URL remoto host:

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

XMLHttpRequest multiorigine

Recupera l'URL remoto nell'app e pubblica i suoi contenuti come 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();

Ti consigliamo di salvare queste risorse localmente, in modo che siano disponibili offline.

Incorporare pagine web esterne

Il tag webview ti consente di incorporare nell'app contenuti web esterni, ad esempio una pagina . Sostituisce gli iframe che puntano a URL remoti, che sono disattivati all'interno delle app di Chrome. Non mi piace iframe, il tag webview viene eseguito in un processo separato. Ciò significa che un exploit al suo interno saranno ancora isolati e non potranno ottenere privilegi elevati. Inoltre, poiché la sua archiviazione (cookie e così via) sia isolato dall'app, per i contenuti web non è in alcun modo possibile accedere ai i dati dell'app.

Aggiungi elemento WebView

L'elemento webview deve includere l'URL dei contenuti di origine e specificarne le dimensioni.

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

Aggiorna proprietà

Per modificare dinamicamente le proprietà src, width e height di un tag webview, puoi Impostare queste proprietà direttamente sull'oggetto JavaScript, oppure utilizzare la funzione DOM setAttribute.

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

Sandbox contenuti locali

La limitazione tramite sandbox consente di pubblicare pagine specifiche in un'origine unica e protetta tramite sandbox. Queste pagine vengono quindi dai criteri di sicurezza del contenuto. Le pagine con sandbox possono utilizzare iframe, scripting incorporato e eval(). Controlla la descrizione del campo manifest per sandbox.

Tuttavia, c'è un compromesso: le pagine con sandbox non possono utilizzare Chrome.* API Se devi svolgere operazioni come eval(), percorri questa strada per essere esente da CSP, ma non potrai usare le cose nuove e interessanti.

Utilizza script incorporati nella sandbox

Di seguito è riportato un esempio di pagina con sandbox che utilizza uno script incorporato e eval():

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

Includi sandbox nel file manifest

Devi includere il campo sandbox nel file manifest ed elencare le pagine dell'app da pubblicare in una sandbox:

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

Apertura di una pagina con sandbox in una finestra

Come per qualsiasi altra pagina dell'app, puoi creare una finestra in cui aprire la pagina con sandbox. Ecco un esempio che crea due finestre, una per la finestra principale dell'app senza sandbox e una per pagina con 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
    }
  });
});

Incorporare una pagina con sandbox nella pagina di un'app

Le pagine con sandbox possono anche essere incorporate in un'altra pagina dell'app utilizzando un 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>

Invio di messaggi a pagine con sandbox

L'invio di un messaggio è composto da due parti: la pubblicazione del messaggio dalla pagina/finestra del mittente, e ascoltare i messaggi sulla pagina/finestra di destinazione.

Pubblica messaggio

Puoi utilizzare postMessage per comunicare tra la tua app e i contenuti con sandbox. Ecco un esempio script in background che pubblica un messaggio nella pagina con sandbox che si apre:

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

In generale, sul web, è necessario specificare l'origine esatta da cui viene inviato il messaggio. Le app di Chrome non hanno accesso all'origine univoca dei contenuti sottoposti a sandbox, quindi puoi inserire nella lista consentita solo tutti come origini accettabili ("*"). Sul lato ricevente, in genere si vuole controllare l'origine; ma poiché i contenuti delle app di Chrome sono inclusi, non è necessario. Per saperne di più, vedi window.postMessage.

Ascolta il messaggio e rispondi

Ecco un esempio di destinatario di messaggi che viene aggiunto alla tua pagina con 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);

Per ulteriori dettagli, dai un'occhiata all'esempio della sandbox.