Внешний контент

Модель безопасности приложений Chrome запрещает внешний контент в iframe и использование встроенных сценариев и eval() . Вы можете обойти эти ограничения, но ваш внешний контент должен быть изолирован от приложения.

Изолированный контент не может напрямую получить доступ к данным приложения или любому из API. Используйте XMLHttpRequests из разных источников и обмен сообщениями для связи между страницей событий и изолированным содержимым, а также косвенного доступа к API.

Ссылки на внешние ресурсы

Политика безопасности контента, используемая приложениями, запрещает использование многих типов удаленных URL-адресов, поэтому вы не можете напрямую ссылаться на внешние изображения, таблицы стилей или шрифты со страницы приложения. Вместо этого вы можете использовать XMLHttpRequests с перекрестным происхождением для получения этих ресурсов, а затем обслуживать их через URL-адреса blob: :.

Требование манифеста

Чтобы иметь возможность выполнять XMLHttpRequests из разных источников, вам необходимо добавить разрешение для хоста удаленного URL-адреса:

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

XMLHttpRequest из перекрестного источника

Загрузите удаленный URL-адрес в приложение и отправьте его содержимое в виде blob: URL:

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. В отличие от iframe, тег webview выполняется в отдельном процессе. Это означает, что эксплойт внутри него по-прежнему будет изолирован и не сможет получить повышенные привилегии. Кроме того, поскольку его хранилище (файлы cookie и т. д.) изолировано от приложения, веб-контент не может получить доступ к каким-либо данным приложения.

Добавить элемент веб-просмотра

Ваш элемент 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() . Ознакомьтесь с описанием поля манифеста для песочницы .

Однако это компромисс: страницы в песочнице не могут использовать API chrome.*. Если вам нужно сделать что-то вроде eval() , идите по этому пути, чтобы освободиться от CSP, но вы не сможете использовать новые интересные возможности.

Используйте встроенные скрипты в песочнице

Вот пример изолированной страницы, в которой используется встроенный скрипт и eval() :

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

Включить песочницу в манифест

Вам необходимо включить поле sandbox в манифест и перечислить страницы приложения, которые будут обслуживаться в песочнице:

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

Открытие изолированной страницы в окне

Как и на любых других страницах приложения, вы можете создать окно, в котором будет открываться изолированная страница. Вот пример, в котором создаются два окна: одно для главного окна приложения, не изолированного в песочнице, и одно для изолированной страницы:

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>

Отправка сообщений на изолированные страницы

Отправка сообщения состоит из двух частей: вам нужно опубликовать сообщение со страницы/окна отправителя и прослушивать сообщения на странице/окне получателя.

Опубликовать сообщение

Вы можете использовать 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);

Для получения более подробной информации ознакомьтесь с примером песочницы .