O modelo de segurança dos apps do Chrome não permite o uso de conteúdo externo em iframes e o uso de inline
scripting e eval()
. É possível substituir essas restrições, mas o conteúdo externo precisa ser
isolados do app.
O conteúdo isolado não pode acessar diretamente os dados do app ou as APIs. Usar origem cruzada XMLHttpRequests e pós-mensagem para comunicação entre a página do evento e o conteúdo no sandbox e acessar as APIs indiretamente.
Referência a recursos externos
A Política de Segurança de Conteúdo usada pelos apps proíbe o uso de vários tipos de URLs remotos.
não podem fazer referência direta a imagens, folhas de estilo ou fontes externas da página de um aplicativo. Em vez disso, você pode
use XMLHttpRequests de origem cruzada para buscar esses recursos e, em seguida, disponibilizá-los por meio de URLs blob:
.
Requisito do manifesto
Para fazer XMLHttpRequests de origem cruzada, você precisará adicionar uma permissão para o URL remoto host:
"permissions": [
"...",
"https://supersweetdomainbutnotcspfriendly.com/"
]
XMLHttpRequest de origem cruzada
Busque o URL remoto no app e exiba o conteúdo dele como um 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();
É recomendável salvar esses recursos localmente para que fiquem disponíveis off-line.
Incorporar páginas da Web externas
Com a tag webview
, você pode incorporar conteúdo externo da Web no seu app, como uma página da Web
página. Ela substitui iframes que apontam para URLs remotos, que são desativados nos apps do Chrome. Não gostei
iframes, a tag webview
é executada em um processo separado. Isso significa que uma exploração dentro dele
ficará isolado e não poderá receber privilégios elevados. Além disso, como seu armazenamento
(cookies, etc.) é isolado do aplicativo, não há como o conteúdo da Web acessar nenhum dos
dados do app.
Adicionar elemento WebView
Seu elemento webview
precisa incluir o URL para o conteúdo de origem e especificar as dimensões dele.
<webview src="http://news.google.com/" width="640" height="480"></webview>
Atualizar propriedades
Para mudar dinamicamente as propriedades src
, width
e height
de uma tag webview
, faça o seguinte:
defina essas propriedades diretamente no objeto JavaScript ou use a função DOM setAttribute
.
document.querySelector('#mywebview').src =
'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
'src', 'http://blog.chromium.org/');
Conteúdo local de sandbox
O sandbox permite que páginas especificadas sejam veiculadas em uma origem exclusiva e em sandbox. Essas páginas são então
isentos da própria Política de Segurança de Conteúdo. As páginas no sandbox podem usar iframes, scripts inline e
eval()
: Confira a descrição do campo do manifesto do sandbox.
Mas há uma desvantagem: páginas no sandbox não podem usar o Chrome.* APIs Se você precisar fazer coisas como
eval()
, siga este caminho para ficar isento da CSP, mas você não poderá usar os recursos novos e legais.
Usar scripts inline no sandbox
Confira um exemplo de página no modo sandbox que usa um script in-line e eval()
:
<html>
<body>
<h1>Woot</h1>
<script>
eval('console.log(\'I am an eval-ed inline script.\')');
</script>
</body>
</html>
Incluir sandbox no manifesto
É necessário incluir o campo sandbox
no manifesto e listar as páginas do app a serem exibidas em um
sandbox:
"sandbox": {
"pages": ["sandboxed.html"]
}
Abrir uma página no modo sandbox em uma janela
Assim como qualquer outra página do app, você pode criar uma janela na qual a página no modo sandbox é aberta. Confira que cria duas janelas, uma para a janela principal do app que não está no sandbox e outra para a página no modo 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
}
});
});
Como incorporar uma página em sandbox a uma página de aplicativo
As páginas no sandbox também podem ser incorporadas a outro app usando um 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>
Como enviar mensagens para páginas no sandbox
O envio de uma mensagem tem duas partes: é necessário postar uma mensagem pela página/janela do remetente, e detectar mensagens na página/janela de recebimento.
Postar mensagem
É possível usar postMessage
para a comunicação entre o app e o conteúdo no sandbox. Aqui está um exemplo
script em segundo plano que publica uma mensagem na página no sandbox que é aberta:
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.', '*');
});
});
De modo geral, na Web, o recomendado é especificar a origem exata de onde a mensagem é enviada. Como os apps do Chrome não têm acesso à origem exclusiva do conteúdo no sandbox, você só pode autorizar todos origens aceitáveis ('*'). No receptor, verifique a origem. mas como o conteúdo dos Aplicativos do Google Chrome está incluído, isso não é necessário. Para saber mais, consulte window.postMessage.
Ouvir mensagem e responder
Veja um exemplo de destinatário de mensagem que é adicionado à sua página no modo 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);
Para mais detalhes, confira o exemplo do sandbox.