Модель безопасности приложений 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);
Для получения более подробной информации ознакомьтесь с примером песочницы .