External Content(外部内容)
警告
重要提示:Chrome 将在所有平台上取消对 Chrome 应用程序的支持。 Chrome 浏览器和 Chrome 网上应用店将继续支持扩展。阅读公告并了解有关迁移应用程序的更多信息。
Chrome 应用程序安全模型不允许 框架(iframe) 中的外部内容以及使用内联脚本和 eval()
。您可以覆盖这些限制,但您的外部内容必须与应用程序隔离。
孤立的内容无法直接访问应用程序的数据或任何 API。使用跨源 XMLHttpRequests 和 post-messaging 在事件页面和沙盒内容之间进行通信并间接访问 API。
API 示例:想玩玩代码吗?查看sandbox示例。
# Referencing external resources(引用外部资源)
应用程序使用的内容安全策略不允许使用多种远程 URL,因此您不能直接从应用程序页面引用外部图像、样式表或字体。相反,您可以使用跨域 XMLHttpRequests 来获取这些资源,然后通过 blob:
URL 为它们提供服务。
# Manifest requirement(要求)
为了能够进行跨域 XMLHttpRequests,您需要为远程 URL 的主机添加权限:
"permissions": [
"...",
"https://supersweetdomainbutnotcspfriendly.com/"
]
# Cross-origin 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();
您可能希望将这些资源保存save在本地,以便它们可以离线使用。
# Embed external web pages(嵌入外部网页)
API 示例:想玩玩代码吗?查看浏览器(browser)示例。
webview
标签允许您在应用程序中嵌入外部网络内容,例如网页。它替换了指向远程 URL 的 iframe,这些 iframe 在 Chrome 应用程序中被禁用。与 iframe 不同,webview
标记在单独的进程中运行。这意味着其中的漏洞利用仍将被隔离并且无法获得提升的权限。此外,由于其存储(cookie
等)与应用程序隔离,因此 Web 内容无法访问应用程序的任何数据。
# Add webview element(添加 webview 元素)
您的 webview
元素必须包含源内容的 URL 并指定其尺寸。
<webview src="http://news.google.com/" width="640" height="480"></webview>
# Update properties(更新属性)
要动态更改 webview
标签的 src
、width
和 height
属性,您可以直接在 JavaScript 对象上设置这些属性,或者使用 setAttribute
DOM 函数。
document.querySelector('#mywebview').src =
'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
'src', 'http://blog.chromium.org/');
# Sandbox local content(沙盒本地内容)
沙盒化允许在沙盒化的唯一来源中提供指定页面。然后,这些页面不受其内容安全策略的约束。沙盒页面可以使用 iframe、内联脚本(inline scripting)和 eval()
。查看沙箱sandbox的清单字段描述。
但这是一个权衡:沙盒页面不能使用 chrome.* API
。如果您需要执行诸如 eval()
之类的操作,请走这条路线以免于 CSP
,但您将无法使用很酷的新东西。
# Use inline scripts in sandbox(在沙箱中使用内联脚本)
这是一个使用内联脚本和 eval()
的示例沙盒页面:
<html>
<body>
<h1>Woot</h1>
<script>
eval('console.log(\'I am an eval-ed inline script.\')');
</script>
</body>
</html>
# Include sandbox in manifest(在清单中包含沙箱)
您需要在清单中包含sandbox
字段并列出要在沙箱中提供的应用程序页面:
"sandbox": {
"pages": ["sandboxed.html"]
}
# Opening a sandboxed page in a window(在窗口中打开沙盒页面)
就像任何其他应用程序页面一样,您可以创建一个沙盒页面在其中打开的窗口。这是一个创建两个窗口的示例,一个用于未沙盒化的主应用程序窗口,一个用于沙盒化页面:
注意:沙盒窗口将无法访问 chrome.app API。如果向
app.window.create
提供回调,它将运行,但不会向其提供沙盒窗口。
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
}
});
});
# Embedding a sandboxed page in an app page(在应用程序页面中嵌入沙盒页面)
沙盒页面也可以使用 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>
# Sending messages to sandboxed pages(向沙盒页面发送消息)
发送消息有两个部分:您需要从发送者page/window发布消息,并在接收page/window上监听消息。
# Post message
您可以使用 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.', '*');
});
});
一般来说,在 Web 上,您希望指定消息发送的确切来源。 Chrome 应用程序无法访问沙盒内容的唯一来源,因此您只能将所有来源列入许可名单,作为可接受的来源 ('*')。在接收端,您一般要检查原产地;但由于包含 Chrome 应用程序内容,因此没有必要。要了解更多信息,请参阅 window.postMessage。
# Listen for message and reply(收听消息并回复)
这是添加到您的沙盒页面的示例消息接收器:
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);
有关更多详细信息,请查看沙箱(sandbox)示例。
By.一粒技术服务