Chrome扩展与应用(一)

Chrome扩展与应用(一)

一、创建并加载一个应用

1.创建一个文本文件,命名为manifest.json

{
    "name": "我的第一个扩展",
    "version": "1.0",
    "description": "这是一个小的示例.",
    "browser_action": {
        "default_icon": "img/icon.png",
        "default_popup": "popup.html"
    },
    "manifest_version": 2
}

2.图标放到img目录中

3.编写html

<!doctype html>
<html>

    <head>
        <title>弹出扩展</title>
    </head>
    <body>
        <img src="img/snow.png"/>
    </body>
</html>

4.加载应用(扩展)

image

二、manifest.json属性

1、browser_action

2、page_action

3、background

4、content_scripts

  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中的脚本只是共享页面的DOM1,而并不共享页面内嵌JavaScript的命名空间。也就是说,如果当前页面中的JavaScript有一个全局变量a,content_scripts中注入的脚本也可以有一个全局变量a,两者不会相互干扰。当然你也无法通过content_scripts访问到页面本身内嵌JavaScript的变量和函数。

5、permissions

6、web_accessible_resources

7、options_page

三、跨域请求

  跨域指的是JavaScript通过XMLHttpRequest请求数据时,调用JavaScript的页面所在的域和被请求页面的域不一致。对于网站来说,浏览器出于安全考虑是不允许跨域。另外,对于域相同,但端口或协议不同时,浏览器也是禁止的。
{

“permissions”: [
://.xtwy.com/*”
]
}

示例:
manifest.json

{
    "name": "我的第一个扩展",
    "version": "1.0",
    "description": "这是一个小的示例.",
    "browser_action": {
        "default_icon": "img/icon.png",
        "default_popup": "popup.html"
    },"permissions": [
        "http://127.0.0.1:8020/*"
    ],
    "manifest_version": 2
}

popup.html

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>数据交互</title>
    </head>
    <body>
        <img src="img/snow.png" />
        <p id="txt"></p>
        <input type="button" id="btn" value="测试" />
        <script src="js/GetContext.js" type="text/javascript" charset="utf-8"></script>
    </body>
</html>

GetContext.js

function httpRequest(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.onreadystatechange = function() {
        if(xhr.readyState == 4) {
            callback(xhr.responseText);
        }
    }
    xhr.send();
}

document.querySelector("#btn").onclick = function() {
    console.log("调用前");
    httpRequest('http://127.0.0.1:8020/page/a.txt', function(txt) {
        alert(txt+"test");
        document.getElementById('txt').innerText = txt;
    });
    console.log("调用后"); 
};

四、常驻后台

  有时我们希望扩展不仅在用户主动发起时(如开启特定页面或点击扩展图标等)才运行,而是希望扩展自动运行并常驻后台来实现一些特定的功能,比如实时提示未读邮件数量、后台播放音乐等等。
  Chrome允许扩展应用在后台常驻一个页面以实现这样的功能。在一些典型的扩展中,UI页面,如popup页面或者options页面,在需要更新一些状态时,会向后台页面请求数据,而当后台页面检测到状态发生改变时,也会通知UI界面刷新。
  在Manifest中指定background域可以使扩展常驻后台。background可以包含三种属性,分别是scripts、page和persistent。如果指定了scripts属性,则Chrome会在扩展启动时自动创建一个包含所有指定脚本的页面;如果指定了page属性,则Chrome会将指定的HTML文件作为后台页面运行。通常我们只需要使用scripts属性即可,除非在后台页面中需要构建特殊的HTML——但一般情况下后台页面的HTML我们是看不到的。persistent属性定义了常驻后台的方式——当其值为true时,表示扩展将一直在后台运行,无论其是否正在工作;当其值为false时,表示扩展在后台按需运行,这就是Chrome后来提出的Event Page。Event Page可以有效减小扩展对内存的消耗,如非必要,请将persistent设置为false。persistent的默认值为true。

五、带选项页面的扩展

指定options_page属性后,扩展图标上的右键菜单会包含“选项”链接。
通过声明unlimitedStorage权限,Chrome扩展和应用可以突破这一限制。
有很多网站提供天气预报的API,比如OpenWeatherMap的API。

1.扩展代码:

manifest.json

{
    "manifest_version": 2,
    "name": "天气预报",
    "version": "1.0",
    "description": "查看未来两周的天气情况",
    "icons": {
        "16": "img/icon16.png",
        "48": "img/icon48.png",
        "128": "img/icon128.png"
    },
    "browser_action": {
        "default_icon": {
            "19": "img/icon19.png",
            "38": "img/icon38.png"
        },
        "default_title": "天气预报",
        "default_popup": "popup.html"
    },
    "options_page": "options.html",
    "permissions": [
        "http://api.openweathermap.org/data/2.5/forecast?q=*"
    ]
}

weather.js

/**
 * ajax请求
 * @param {Object} url
 * @param {Object} callback
 */
function httpRequest(url, callback){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            callback(xhr.responseText);
        }
    }
    xhr.send();
}
/**
 * 显示天气
 * @param {Object} result
 */
function showWeather(result){
    result = JSON.parse(result);
    var list = result.list;
    var table = '<table><tr><th>日期</th><th>天气</th><th>最低温度</th><th>最高温度</th></tr>';
    for(var i in list){
        var d = new Date(list[i].dt*1000);
        table += '<tr>';
        table += '<td>'+d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()+'</td>';
        table += '<td>'+list[i].weather[0].description+'</td>';
        table += '<td>'+Math.round(list[i].temp.min-273.15)+' °C</td>';
        table += '<td>'+Math.round(list[i].temp.max-273.15)+' °C</td>';
        table += '</tr>';
    }
    table += '</table>';
    document.getElementById('weather').innerHTML = table;
}
/**
 * 读取本地存储
 */
var city = localStorage.city;
city = city?city:'beijing';
var url = 'http://api.openweathermap.org/data/2.5/forecast/daily?q='+city+',china&lang=zh_cn';
//ajax请求调用
httpRequest(url, showWeather);

popup.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            body {
                width: 520px;
                height: 270px;
            }

            table {
                font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
                font-size: 12px;
                width: 480px;
                text-align: left;
                border-collapse: collapse;
                border: 1px solid #69c;
                margin: 20px;
                cursor: default;
            }

            table th {
                font-weight: normal;
                font-size: 14px;
                color: #039;
                border-bottom: 1px dashed #69c;
                padding: 12px 17px;
                white-space: nowrap;
            }

            table td {
                color: #669;
                padding: 7px 17px;
                white-space: nowrap;
            }

            table tbody tr:hover td {
                color: #339;
                background: #d0dafd;
            }
        </style>
    </head>
    <body>
        <div id="weather">载入中……</div>
        <script src="js/weather.js"></script>
    </body>
</html>

2.网页代码

options.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>设定城市</title>
    </head>
    <body>
        <input type="text" id="city" />
        <input type="button" id="save" value="保存" />
        <script src="js/options.js"></script>
    </body>
</html>

options.js

//存储本地数据
var city = localStorage.city;
city = city?city:'beijing';
document.getElementById('city').value = city;
document.getElementById('save').onclick = function(){
    localStorage.city = document.getElementById('city').value;
    alert('保存成功。');
}

六、window.postMessage实现跨域通信

以下必须在web服务器中设置:
X-Frame-Options是什么?
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM http://xtwy.com/
第一个例子告诉浏览器不要(DENY)把这个网页放在iFrame内,通常的目的就是要帮助用户对抗点击劫持。
第二个例子告诉浏览器只有当架设iFrame的网站与发出X-Frame-Options的网站相同,才能显示发出X-Frame-Options网页的内容。
第三个例子告诉浏览器这个网页只能放在http://xtwy.com//网页架设的iFrame内。

1.发送消息的”postMessage”方法

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<title>数据发送端</title>
<!--实现跨域通信-->
<iframe id="proxy" src="http://127.0.0.1:8020/postMessage/index.html"  style="display: none"></iframe>
<script type="text/javascript">
    var iframe = document.getElementById('proxy');
    var win = iframe.contentWindow;
    //周期性的发送消息
    setInterval(function(){
        var message = '现在的时间是: ' + (new Date().getTime());
        console.log('发送消息:  ' + message);
        win.postMessage(message,'http://127.0.0.1:8020/');
    },6000);

    //监听消息反馈
    window.addEventListener('message',function(event) {
        if(event.origin !== 'http://127.0.0.1:8020') return;
        console.log('接受响应:  ',event.data);
    },false);
</script>
</body>
</html>

向外界窗口发送消息:
otherWindow.postMessage(message, targetOrigin);
otherWindow: 指目标窗口,也就是给哪个window发消息,是 window.frames 属性的成员或者由 window.open 方法创建的窗口
参数说明:
message: 是要发送的消息,类型为 String、Object (IE8、9 不支持)
targetOrigin: 是限定消息接收范围,不限制请使用 ‘*’

2.接受信息的”message”事件

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>数据接收端</title>
    </head>
    <body>
        数据接收端。
        <script>
            window.addEventListener("message", receiveMessage, false);

            function receiveMessage(event) {
                //data.msg 将是从另一个域发送来的
                if(event.origin !== "http://localhost:63342")
                    return;
                //输出内容
                console.log('接受消息:' + event.data,event);
                //回发
                event.source.postMessage('消息返回!',event.origin);
            }
        </script>
    </body>
</html>

结果:
image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值