外部内容

Chrome 应用安全模型既禁止在 iframe 中使用外部内容,也禁止使用内嵌内容 脚本和 eval()。你可以覆盖这些限制,但外部内容必须 与应用隔离开来

隔离的内容无法直接访问应用的数据或任何 API。使用跨源 以及通过 XMLHttpRequests 和后消息在事件页面和沙盒化内容之间进行通信 间接访问 API

引用外部资源

应用使用的内容安全政策禁止使用多种远程网址,因此 无法直接引用应用页面中的外来图片、样式表或字体。相反,您可以 使用跨源 XMLHttpRequest 获取这些资源,然后通过 blob: 网址提供这些资源。

清单要求

为了能够执行跨源 XMLHttpRequests,您需要为远程 网址 的 主讲人:

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

跨源 XMLHttpRequest

将远程网址提取到应用中,并将其内容作为 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();

建议您将这些资源保存到本地,以供离线使用。

嵌入外部网页

利用 webview 标记,您可以在应用中嵌入外部 Web 内容,例如 Web 页面。它取代了指向远程网址的 iframe(在 Chrome 应用中已停用)。取消点赞 iframe 中,webview 代码会在一个单独的进程中运行。这意味着,这个容器内的漏洞 并且无法获得提升的权限。此外,由于它的存储 (Cookie 等)与应用隔离开来,因此网页内容无法访问 应用的数据

添加 WebView 元素

您的 webview 元素必须包含指向源内容的网址并指定其尺寸。

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

更新属性

如需动态更改 webview 标记的 srcwidthheight 属性,您可以执行以下任一操作 直接在 JavaScript 对象上设置这些属性,或使用 setAttribute DOM 函数。

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

沙盒本地内容

通过沙盒化,允许在沙盒化的唯一源中提供指定网页。然后,这些网页会 不受其内容安全政策的约束。沙盒化网页可以使用 iframe、内嵌脚本和 eval()。请查看 sandbox 的清单字段说明。

不过,您仍需权衡利弊:沙盒化页面无法使用 Chrome。*API。如果您需要执行诸如 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);

如需了解详情,请参阅沙盒示例。