Chrome扩展程序 - 注入的iframe无法访问Chrome浏览器动作或chrome.tabs或AngularJS

时间:2014-10-25 00:54:52

标签: javascript angularjs iframe google-chrome-extension content-script

我有一个Chrome扩展程序,可以通过浏览器操作点击来切换侧边栏。侧边栏包含带有本地(Chrome扩展程序)源的iframe。我认为iframe中的页面将被视为本地chrome扩展文件,可以对chrome API等进行开放访问。但是,我在 web 控制台中不断收到以下错误:

未捕获的TypeError:无法读取未定义的属性'onClicked'< - background.js

TypeError:无法读取undefined< - sidebar.js

的属性'query'

如何获取它以便使用上下文脚本注入的iframe可以访问本地chrome环境?

以下代码:

sidebar.js:

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


myApp.service('pageInfoService', function() {
    this.getInfo = function(callback) {
        var model = {};

        chrome.tabs.query({
            'active': true,               // Select active tabs
            lastFocusedWindow: true     // In the current window
        },
        function (tabs) {
            if (tabs.length > 0)
            {
                model.title = tabs[0].title;
                model.url = tabs[0].url;

                chrome.tabs.sendMessage(tabs[0].id, { 'action': 'PageInfo' }, function (response) {
                    model.pageInfos = response;
                    console.log("popup js: " + model.pageInfos);
                    callback(model);
                });
            }

        });
    };
});

myApp.controller("PageController", function ($scope, pageInfoService) {
    $scope.message = "This extension identifies the photos on this page!";

    pageInfoService.getInfo(function (info) {
        $scope.title = info.title;
        $scope.url = info.url;
        $scope.pageInfos = info.pageInfos;
        $scope.place_name = info.place_name;
        $scope.$apply();
    });
});

background.js

console.log( 'Background.html starting!' );

// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
    // No tabs or host permissions needed!
    console.log('Toggling sidebar on ' + tab.url);

    // send message to current tab when clicked
    var tabId = tab.id;
    console.log("tab.id: " + tabId);
    chrome.tabs.query({active: true, currentWindow: true}, function(tab) {

        chrome.tabs.sendMessage(
            //Selected tab id
            tabId,
            //Params inside a object data
            {callFunction: "toggleSidebar"}, 
            //Optional callback function
            function(response) {
                console.log(response);
            }
        );
    });


    console.log('Done toggling sidebar!');

});

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    if(request.cmd == "read_file") {
        $.ajax({
            url: chrome.extension.getURL("sidebar.html"),
            dataType: "html",
            success: sendResponse
        });
    }
})

chrome.runtime.onMessage.addListener(
    function(msg, sender, sendResponse) {
        console.log(sender.tab ?
                    "from a content script:" + sender.tab.url :
                    "from the extension");
        if (msg.command == "read_info"){
            console.log(JSON.parse(JSON.stringify(msg.myInfo)));
            sendResponse({command: "done"});
        }
    }
);

console.log( 'Background.html done.' );

1 个答案:

答案 0 :(得分:7)

唯一可以访问所有chrome.*扩展程序API的网页是在扩展程序来源和Chrome扩展程序中运行的网页。

当扩展页面嵌入iframe时,其扩展运行时相当于内容脚本:该页面只能使用跨源XMLHttpRequest和一些扩展API(messaging和其他一些方法。 chrome.runtime / chrome.extension名称空间)。

如果您希望将其他Chrome API的功能提供给您的iframe,则必须从background page调用这些API,并使用messaging API代理来自iframe的请求背景页面和背面。幸运的是,大多数Chrome扩展API在设计上都是异步的,因此更改代码以使用这些代理并不困难。