私が構築しているクロム拡張機能をAngularJSで動作させる方法を理解しようとしている日々です。問題は、リモート リソースに正常にアクセスできないことです。angular を使用しない限り、メインの html とサンドボックスの間で通信する方法は、Web pkg.jsで見つけた pub/sub javascript を使用することでした。この方法で、main.js で外部 URL を呼び出すことができました。取得したデータをサブスクライブした JavaScript に渡します。
アーキテクチャをよりよく理解できるように、コードを大幅に簡素化しました。angular が機能しないという事実とは別に、完全に機能するいくつかのテストリソースを次に示します:/
私のマニフェストには、次の関連部分があります。
{
...
"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 は非常にシンプルです。タブを作成し、Angular コードをホストする 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には何もレンダリングされません:(
このすべてから抜け出す方法を理解するのを手伝ってくれる人はいますか?
ところで、私は何らかの形でそうするように強制されました.plnkrにあった最初のバージョンは喜んでコントローラー内で$httpを使用しましたが、これはchrome拡張機能では禁止されているようです...私もamplifyjsを使用しようとしましたが、しませんでしたiframe とそのコンテナーの間の通信を機能させるために出てきます。
どうもありがとう!