谷歌浏览器插件开发
来源:互联网 发布:纸张好的本子推荐 知乎 编辑:程序博客网 时间:2024/06/10 03:27
谷歌浏览器插件开发
简介
Chrome扩展主要用于对浏览器功能的增强,它更强调与浏览器相结合。比如Chrome扩展可以在浏览器的工具栏和地址栏中显示图标,它可以更改用户当前浏览的网页中的内容,直接操作浏览页面的DOM树等。这里用它来采集数据,类似于爬虫,然后将处理的数据发送到指定接口,导入数据库。
还有一种Chrome应用,但与浏览器内容相对独立,这里不介绍。
开发环境
开发浏览器插件不需要特别的工具,只需要装上谷歌浏览器, 一个记事本足矣。调试什么都可以在浏览器进行。
目录结构
这里写的是简单的插件,基本目录结构如下:
谷歌浏览器简单的插件实际上就是一个拓展的网页,所以和普通的HTML的结构没什么特殊之处,上面的js、images完全可以是你喜欢的名称,引用时路径写对就行,需要注意的是,插件必须包含一个manifest.json文件(必须是这个名字),此文件描述了插件的一些基本信息,安装插件时会读取插件相关信息。
插件的html页面可以引用外部的js文件,但是注意,不能直接在页面里面直接写JavaScript脚本,是不会执行,必须是引用的脚本,切记
manifest.json详解
manifest.json是插件最重要的配置和描述文件,下面用我的例子来说说
{ "manifest_version": 2, "name": "采集插件", "version": "1.0", "description": "获取网页数据,保存直接到OA系统", "content_scripts": [ { "matches": ["https://abc.xxxx.com/*"], "run_at": "document_end", "js": ["js/getdata.js"] } ], "browser_action": { "default_icon": { "16": "images/icon16.png", "32": "images/icon32.png", "38": "images/icon38.png", "48": "images/icon48.png", "64": "images/icon64.png", "128": "images/icon128.png" }, "default_title": "状态", "default_popup": "popup.html" }, "options_page": "options.html", "permissions": [ "storage", "https://abc.xxxx.com/*", "http://127.0.0.1:8080/*" ]}
name定义了扩展的名称,
version定义了扩展的版本,
description定义了扩展的描述,
icons定义了扩展相关图标文件的位置,谷歌会根据需要选择合适大小的图标
version的值最多可以是由三个圆点分为四段的版本号,每段只能是数字,每段数字不能大于65535且不能以0开头(可以是0,但不可以是0123),版本号段左侧为高位,比如1.0.2.0版本比1.0.0.1版本更高。每次更新扩展时,新的版本号必须比之前的版本号高。
browser_action指定扩展的图标放在Chrome的工具栏中,
browser_action中的default_icon属性定义了相应图标文件的位置,
default_title定义了当用户鼠标悬停于扩展图标上所显示的文字,default_popup则定义了当用户单击扩展图标时所显示页面的文件位置,
content_scripts属性可以指定将哪些脚本何时注入到哪些页面中,当用户访问这些页面后,相应脚本即可自动运行,从而对页面DOM进行操作。
Manifest的content_scripts属性值为数组类型,数组的每个元素可以包含matches、exclude_matches、css、js、run_at、all_frames、include_globs和exclude_globs等属性。
其中matches属性定义了哪些页面会被注入脚本,exclude_matches则定义了哪些页面不会被注入脚本,css和js对应要注入的样式表和JavaScript;
run_at定义了何时进行注入,
另外,all_frames可以定义脚本是否会注入到嵌入式框架中,
include_globs和exclude_globs则是全局URL匹配,最终脚本是否会被注入由matches、exclude_matches、include_globs和exclude_globs的值共同决定。
简单的说,如果URL匹配mathces值的同时也匹配include_globs的值,会被注入;如果URL匹配exclude_matches的值或者匹配exclude_globs的值,则不会被注入。
content_scripts中的脚本只是共享页面的DOM树,而并不共享页面内嵌JavaScript的命名空间。
也就是说,如果当前页面中的JavaScript有一个全局变量a,content_scripts中注入的脚本也可以有一个全局变量a,两者不会相互干扰。当然你也无法通过content_scripts访问到页面本身内嵌JavaScript的变量和函数。
Manifest的permissions属性中声明需要谷歌拓展API的storage权限和跨域的权限。
项目业务代码等
业务部分
以下是get_data.js代码,主要业务操作在这里
timeStart="";timeEnd="";timeEnd_collect=""; //采集结束时间,程序到这时间终止//encode要发送到OA系统的数据function encodeFormData(data){ if(!data) return ''; var pairs = []; for(var name in data){ if(!data.hasOwnProperty(name)) continue; if(typeof data[name] === 'function') continue; var value = data[name].toString(); name = encodeURIComponent(name.replace('%20','+')); value = encodeURIComponent(value.replace('%20','+')); pairs.push(name+'='+value); } return pairs.join('&');}//获取,处理页面数据function get_data(){ var trs = window.frames["MainIframe"].document.getElementById("table_data_tbody").children; var datas=[]; for(var i=0;i<trs.length;i++){ var tds =trs[i].childNodes; var data_tmp= { STARTTIME:tds[1].innerText, ENDTIME:tds[2].innerText, ZUOXI:tds[3].innerText, ZUOXI_ID:tds[4].innerText, FROM_NUM:tds[5].innerText, TO_NUM:tds[6].innerText, CALL_TYPE:tds[7].innerText, DURATION:tds[8].innerText, SATISFACTION:tds[9].innerText, ACID:tds[10].innerText }; datas[i]=data_tmp; } var s = JSON.stringify(datas); var data2sent={ data:s } httpRequest('http://127.0.0.1:8080/invCloudOA/appuser/calllog2db',encodeFormData(data2sent),function(result){ html = result; console.log(html); });}//模拟用户操作,发送请求给accfunction sent_req(){ chrome.storage.local.set({"log":"模拟用户操作,修改时间参数"}); var timestamp_end = Date.parse(new Date(timeEnd)); window.frames["MainIframe"].document.getElementById("type_duration").click(); window.frames["MainIframe"].document.getElementById("timeStart").value=timeStart; window.frames["MainIframe"].document.getElementById("timeEnd").value=timeEnd; window.frames["MainIframe"].document.getElementById("btnOk").click(); chrome.storage.local.set({"log":"发送请求,延时处理返回数据"}); //延时数据处理 setTimeout(get_data,12000); //设置新的时间 chrome.storage.local.set({"log":"时间参数修改"}); timeStart=timeEnd; var end_timestamp = Date.parse(new Date(timeEnd)); var new_end_date = new Date(); new_end_date.setTime(end_timestamp+60*60*1000); timeEnd=new_end_date.format('yyyy-MM-dd hh:mm:ss'); var p = { timeStart:timeStart, timeEnd:timeEnd, } chrome.storage.local.set(p,function(){}); chrome.storage.local.set({"log":"数据处理完成,准备发给OA"}); setTimeout(sent_req, 10000);}//构造请求,发给OAfunction httpRequest(url,data, callback){ var xhr = new XMLHttpRequest(); xhr.open('post',url); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); chrome.storage.local.set({"log":"发送数据给OA,OA处理中"}); xhr.send(data);}//时间格式化工具Date.prototype.format = function(format) { var date = { "M+": this.getMonth() + 1, "d+": this.getDate(), "h+": this.getHours(), "m+": this.getMinutes(), "s+": this.getSeconds(), "q+": Math.floor((this.getMonth() + 3) / 3), "S+": this.getMilliseconds() }; if (/(y+)/i.test(format)) { format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length)); } for (var k in date) { if (new RegExp("(" + k + ")").test(format)) { format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? date[k] : ("00" + date[k]).substr(("" + date[k]).length)); } } return format;}//程序入口chrome.storage.local.get("isenable", function(obj) { chrome.storage.local.get("timeStart", function(obj) { timeStart=obj.timeStart; }); chrome.storage.local.get("timeEnd", function(obj) { timeEnd=obj.timeEnd; }); if(obj.isenable){ setTimeout(sent_req,6000); chrome.storage.local.set({"log":"插件已经正常开启!"}); }});
以上是点击插件图标弹出的页面,预想是用来显示运行时的日志的,效果不好,懒得改了。
<html> <head> <title>参数设定</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> </head> <body> <div style="width: 300px;height:60px;text-align: center"> <br/> <p id="log"> 插件日志 </p> </div> <script src="js/popup.js"></script> </body></html>
插件的配置部分
配置页面,没追求,自己随便写一个简陋的页面
<html> <head> <title>参数设定</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> </head> <style> .big{ font-size: 30px; } .biginput{ width: 300px; height: 50px; font-size: 30px; } </style> <body> <div style="width: 80%;height:auto;text-align: center"> <br/> <span class="big">开始时间:</span><input class="biginput" type="text" id="timeStart" value="2017-11-01 00:00:00"/><br/><br/> <span class="big">结束时间:</span><input class="biginput" type="text" id="timeEnd" value="2017-11-01 00:30:00"/><br/><br/> <span class="big">是否启用:</span><input type="checkbox" id="isenable" /><br/><br/> <input type="button" class="biginput" id="save" value="保存" /><br/> </div> <script src="js/options.js"></script> </body></html>
配置页面引用的脚本,一看就懂
//加载数据,显示目前的配置window.onload=function(){ chrome.storage.local.get("isenable", function(obj) { document.getElementById('isenable').checked=obj.isenable }); chrome.storage.local.get("timeStart", function(obj) { document.getElementById('timeStart').value=obj.timeStart }); chrome.storage.local.get("timeEnd", function(obj) { document.getElementById('timeEnd').value=obj.timeEnd });}//保存document.getElementById('save').onclick = function(){ var timeStart = document.getElementById('timeStart').value; var timeEnd = document.getElementById('timeEnd').value; var isenable = document.getElementById('isenable').checked; var p = { timeStart:timeStart, timeEnd:timeEnd, isenable:isenable } chrome.storage.local.set(p,function(){ alert('设置已保存'); } );}
运行
打开插件管理
加载已经解压的应用,选择对应文件夹
发布
直接点击上图的打包拓展程序,选择文件夹,密钥可选,如果是升级,可以选择首次自动生成的密钥
生成插件文件和证书
安装
打开拓展页面,直接拉过去,确定即可
这里特别说一下,谷歌插件支持三种方法中的一种来储存数据:
第一种是使用HTML5的localStorage;
第二种是使用Chrome提供的存储API;
第三种是使用Web SQL Database。
localStorage就是h5自带的
Chrome提供的存储API和localStorage相似,拓展一些功能
如果储存区域指定为sync,数据可以自动同步;
content_scripts可以直接读取数据,而不必通过background页面;
在隐身模式下仍然可以读出之前存储的数据;
读写速度更快;
用户数据可以以对象的类型保存。
localStorage是基于域名的,而content_scripts是注入到用户当前浏览页面中的,如果content_scripts直接读取localStorage,所读取到的数据是用户当前浏览页面所在域中的。所以通常的解决办法是content_scripts通过runtime.sendMessage和background通信,由background读写扩展所在域(通常是chrome-extension://extension-id/)的localStorage,然后再传递给content_scripts。
Chrome提供的存储API就没有这些问题,可以跨页面读取,666
参考文档:Chrome拓展应用及开发
- 开发谷歌浏览器插件
- 谷歌浏览器插件开发
- 谷歌浏览器插件开发
- 【JavaScript】开发谷歌浏览器插件
- 谷歌浏览器插件
- 谷歌浏览器插件
- Chrome(谷歌浏览器) 程序开发32个常用插件
- [Chrome]谷歌浏览器插件开发:HelloChrome插件的开发过程
- 初识----浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android浏览器插件开发
- Android 浏览器插件开发
- linux用cat命令进入一个很大的文件,如何退出?
- VMware Workstation虚拟机 12.5.7安装
- HDU2012
- 111. Minimum Depth of Binary Tree
- python
- 谷歌浏览器插件开发
- MySQl生产备份实战应用指南
- ORA-01034: ORACLE not available
- 李艳鹏:技术人如何修炼内功
- 欢迎使用CSDN-markdown编辑器
- attention机制
- 卡尔曼滤波算法
- Android5.0,6.0,7.0新特性整理
- 金蝶K3库存账龄分析表(优化)