带有Angularjs的Chrome扩展程序(沙盒)

时间:2013-11-03 12:50:12

标签: javascript angularjs iframe google-chrome-extension sandbox

这几天我正在试图弄清楚如何使用AngularJS制作Chrome扩展程序。 问题是我无法成功访问远程资源;只要我没有使用angular,我在主html和沙箱之间进行通信的方式是使用我在网络pkg.js找到的pub / sub javascript,这样我就可以在主要网址中调用外部网址.js并将检索到的数据传回订阅的javascripts。

我大大简化了我的代码,以便您可以更好地理解架构。以下是一些测试资源,与事实完全不同......角度不起作用:/

我的清单有以下相关部分:

{
...
"background": {
 "scripts": ["new/ext/background.js"],
 "persistent": false
},
"permissions": [
 "tabs",
 "http://*.mysite.com/*"
],
"sandbox": {
 "pages": [ "new/testmain.html" ]
},
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}

我的background.js很简单:它只是创建一个标签并调用一个html来托管角度代码:

chrome.browserAction.onClicked.addListener(function (tab) {
  chrome.tabs.create({'url': chrome.extension.getURL('/new/main.html')}, function (tab) {     });
});

main.html也非常简单:只有一些脚本包含和iframe:

<!doctype html>
<html>
<head>
  <title>Testing angular</title>

  <script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>

  <!-- custom scripts -->
  <script type="text/javascript" src="/lib/pkg.js"></script>

</head>
  <body style="height: 100%">
  <h1>Iframe below</h1>
  <iframe id="iframe" src="testmain.html" width="100%" height="100%" frameborder="none"></iframe>

  <script type="text/javascript" src="testmain.js"></script>

</body>
</html>

testmain.js只是订阅一个事件,如果收到它,它会发布虚拟数据:

iframe = document.getElementById("iframe");
$.pkg.init(iframe.contentWindow);

$.pkg.listen("items", function () {
  console.log("[testmain.js] received items message");
  items = [
      { name:"foo", age: 12 },
      { name:"bar", age: 11 },
      { name:"mickey", age: 15},
      { name: "donald", age: 27}
  ];
  $.pkg.send("response", [items]);
  console.log("[testmain.js] sent response");
});

现在让我们来testmain.html:

<!DOCTYPE html>
<html data-ng-app="App" data-ng-csp>
<head>
  <title></title>
</head>
<body ng-controller="TodoCtrl">
  <div ng-repeat="item in testitems">
    <ul>
      <li>{{item.name}}</li>
    </ul>
  </div>
  <script type='text/javascript' src="lib/jquery.min.js"></script>
  <script type="text/javascript" src="lib/angular.min.js"></script>
  <script src="/lib/pkg.js"></script>
  <script src="app/testapp.js"></script>
</body>
</html>

最后,这是testapp.js:

var App = angular.module('App', []);

App.controller('TodoCtrl', function($scope) {

  //test
  $.pkg.init(window.top);
  $.pkg.send("items");
  console.log("[testapp.js] sent message items");
  $.pkg.listen("response", function(res){
    console.log("[testapp.js] received " + res.length + " items");
    $scope.testitems = res;
    for (i = 0; i < $scope.testitems.length; i++) {
       console.log("[testapp.js] testitem: " + $scope.testitems[i].name);
    }
  });
});

控制器只是与包含iframe的destination = html进行通信。然后它发送一条请求数据的消息,然后将其发回(侦听)。

如果我尝试从控制台运行任何手动命令来获取$ scope变量,那么根本没有成功:

document.getElementById('iframe')
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb".  The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb".  The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
Sandbox access violation: Blocked a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb" from accessing a frame at "chrome-extension://jcnppfndabbcgbdcnjncnoddmhmkmmbb".  The frame being accessed is sandboxed and lacks the "allow-same-origin" flag.
<iframe id="iframe" src="testmain.html" width="100%" height="100%" frameborder="none"></iframe>

这是控制台中发生的事情:

[testapp.js] sent message items testapp.js:8
[testmain.js] received items message testmain.js:5
[testmain.js] sent response testmain.js:13
[testapp.js] received 4 items testapp.js:10
[testapp.js] testitem: pippo testapp.js:13
[testapp.js] testitem: pluto testapp.js:13
[testapp.js] testitem: paperino testapp.js:13
[testapp.js] testitem: minnie testapp.js:13

正如您可能注意到的那样,通信发生,$ scope.testitems变量设置正确。但是在iframe上没有呈现任何内容:(

任何人都可以帮我弄清楚如何摆脱这一切吗?

Btw,我在某种程度上被迫这样做 - 第一个版本在plnkr上很高兴地使用了控制器内的$ http,但这似乎在chrome扩展中被禁止了...... 我也尝试使用amplifyjs,但没有出来让iframe和它的容器之间的通信工作。

非常感谢!

0 个答案:

没有答案