首页 编程 正文
692

chrome扩展开发的一些例子

chrome扩展主要有三个地方是可编码的:1)background scripts. 2)popup scripts. 3)content scripts.

background scripts 通过在manifest.json中设置background属性来配置js,
例如:
"background":{
    "scripts": ["background.js", "common.js"]
}
background scripts中Api的权限受制于 ”permissions"的设置。
调试background scripts 通过: 扩展管理 -> 开启开发者模式 -> 在相应的扩展下打开”检查视图".

所谓popup 也就是点击了扩展图标会弹出一个定制的页面来,页面通常命名为popup.html, 它可以引入css, js, image, 就如编写普通的web页面一样。但是在给元素设置event listener的时候要注意,不能使用内联的方式设置。
比如,在 popup.html页面这样写是不对的:<a onclick="test_click()">TestClick</a>
应该将事件绑定放到外联js脚本中,比如在popup.js中这样绑定:
window.onload = function (){
    document.getElementById('testA').onclick = function (){.....};
};
在mainifest.json中的配置形如:
"browser_action":{
    "default_popup": "popup.html"
}
调试popup scripts, 先点击扩展图标,打开popup界面,在popup页面任意空白处右键->检查,即可打开popup.html的开发者工具,注意popup必须得维持打开状态,若scripts中利用了window.close()将popup关闭,那么开发者工具也会随之关闭。

content scripts是扩展向web页面插入的代码,所以它可以访问页面的DOM,BOM,但是它是在沙箱中运行,所以它仅能有限地访问页面的一些变量和函数。笔者就曾经遇到过使用jQuery触发点击事件无效的情形,例如:jQuery('#do_btn').click()无效,改成document.getElementById('do_btn').click()才行。
在mainifest.json中配置形如:
"content_scripts":[
{
"matches":["<all_urls>"],
"js":["js/jquery.min.js","js/main.js"],
"run_at":"document_end"
}
]
"matches"配置决定了其所在段的js代码只能运行在相匹配的目标站点中。
调试content scripts直接可以在页面的开发者工具中查看console .

接下来就是送干货了。

一、popup scripts 调用 XMLHttpRequest.
如果xhr调用的是扩展内的文件,那么不会涉及到跨域,直接调用就好
var xhr = new XMLHttpRequest();
xhr.open('GET', 'config.json', true);
xhr.onreadystatechange = function (){if (xhr.readyState==4){console.log(xhr.responseText)}};
xhr.send();
如果xhr调用的是远程server,那么就会触发跨域了,此时需要在permissons中配置目标站点的url或者"<all_urls>", 写法同上。

二、background scripts 中向页面注入js, 相当于注入content scripts
chrome.browserAction.onClicked.addListener(function (tab){
    chrome.tabs.executeScript(tab.id, {
        file: "js/jquery.min.js",
        allFrames: true,
        runAt: "document_idle"
    });
    chrome.tabs.executeScript(tab.id, {
        file: "js/content.js",
        allFrames: true,
        runAt: "document_idle"
    });
});
当用户点击了扩展图标之后就会执行jquery和content.js.
注意:
permissions要相应地配置注入站点的url,如:"permissions": [
"https://debugger.eu2.netsuite.com/*"
]
content_scripts无需配置。

三、content scripts 向 background scripts 通信:
content.js:
chrome.extension.sendRequest({data1:data1, data2:data2});

background.js:
chrome.extension.onRequest.addListener(function(data){
       console.log(data.data1, data.data2);
});
//后来的版本建议使用runtime.sendMessage, runtime.onMessage.

四、popup scripts 向 content scripts通信:
popup.js:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {data1: data1, data2: data2}, function(response) {
              console.log(response.feedback); //goodbye
        });
});

content.js:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    console.log(request.data1, request.data2);
    sendResponse({feedback: "goodbye"}); //返回给发送者
    return true; //加上这个貌似可以解决一个报错的问题。
});

五、content scripts 向 页面注入代码:
虽然说,在content scripts中可以引用页面的window, document这些对象,但是由于沙箱限制,有些功能并不能实现,比如笔者想在content scripts给window.onerror设置监听函数就没有想像当中那么简单,通过谷歌搜索到此项目https://github.com/barbushin/javascript-errors-notifier/blob/master/content.js 得到了解决方法。
content.js:
(function (){
    if (location.href.indexOf('sample.com') === -1) return; //只给sample.com注入
   
    function codeToInject(){
        var oldError = window.onerror;
        window.onerror = function (msg, url, line, column, errorObj){
            console.log(msg + "\t" + line + ':' + column);
            localStorage.setItem(location.pathname, JSON.stringify({msg:msg, url:url, line:line, col:column}));
            typeof(oldError) == 'function' && oldError(msg, url, line, column, errorObj);
        };
    }
    var script = document.createElement('script');
    script.textContent = '(' + codeToInject + '())';
    (document.head || document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
})();
















正在加载评论...