目录 本文首发于《程序员》杂志2017年第9、10、11期,下面的版本又经过进一步的修订。导读搜索是程序员的灵魂,为了提升搜索的效率,以便更快的查询信息,我试着同时搜索4个网站,分别是百度、Google、维基、Bing。一个可行的做法就是网页中嵌入4个iframe,通过js拼接前面4个搜索引擎的Search URL并依次在iframe中加载。这个构思丝毫没有问题,简单粗暴。然而就是这么简单的功能,也无法实现。由于Google网站在HTML的response header中添加了 Nginx反向代理Google显然不会,既然问题出在 location / {
more_clear_headers 'X-Frame-Options';
}为了让 server {
listen 80;
server_name louis.google.com;
location / {
proxy_pass https://www.google.com/;
more_clear_headers 'X-Frame-Options';
}
}以上的配置有什么问题吗?且不说http直接转https的问题,即使能转发,实际上由于Google的安全策略限制,我们也访问不了Google首页! 最终我使用了一个Nginx Google代理模块 server {
listen 80;
server_name louis.google.com;
resolver 192.168.1.1; # 需要设置为当前路由的网关
location / {
google on;
google_robots_allow on;
more_clear_headers 'X-Frame-Options';
}
}以上,通过实现一个Google网站的反向代理,代理的同时去掉了响应头域中的 nginx方案有一个明显的缺陷是,配置中resolver对应的网关IP IHeader缘起nginx方案的这个缺陷多少有些麻烦,恰好Chrome Extension可以定制headers,为了解决这个问题,我便尝试开发Chrome Extension。(使用Chrome以来,我下载试用过无数的Chrome Extension。每每看到一款优秀的Extension,都要激动好久,总有一种相见恨晚的感觉。Extension以其强大的定制能力,神奇的运行机制征服了无数的开发者,我也不例外。然而无论多少次的学习和模仿,最终的目的还是为了使用,故开发一款定制请求的Extension势在必行。)由于Chrome浏览器与网页的天然联系,使用Chrome Extension的方式去掉响应头域字段,比其它方案要更加简单高效。 要知道,Chrome Extension提供的API中有 于是新建项目,取名 IHeader 。目录结构如下:
其中,_locales是国际化配置,目前IHeader支持中文和英文两种语言。 res是资源目录,index.html是extension的首页,options.html是选项页面。 manifest.json是extension的声明配置(总入口),在这里配置extension的名称、版本号、图标、快捷键、资源路径以及权限等。 manifest.json贴出来如下: {
"name": "IHeader", // 扩展名称
"version": "1.1.0", // 扩展版本号
"icons": { // 上传到chrome webstore需要32px、64px、128px边长的方形图标
"128": "res/images/lightning_green128.png",
"32": "res/images/lightning_green.png",
"64": "res/images/lightning_green64.png"
},
"page_action": { // 扩展的一种类型,说明这是页面级的扩展
"default_title": "IHeader", // 默认名称
"default_icon": "res/images/lightning_default.png", // 默认图标
"default_popup": "res/index.html" // 点击时弹出的页面路径
},
"background": { // 扩展在后台运行的脚本
"persistent": true, // 由于后台脚本需要持续运行,需要设置为true,反之扩展不活动时可能被浏览器关闭
"scripts": ["res/js/message.js", "res/js/background.js"] // 指定运行的脚本,实际上Chrome会启用一个匿名的html去引用这些js脚本。等同于"pages":["background.html"]这种方式(注意这两种互斥,同时设置时,后一种有效)
},
"commands": { // 指定快捷键
"toggle_status": { // 快捷命令的名称
"suggested_key": { // 快捷命令的热键
"default": "Alt+H",
"windows": "Alt+H",
"mac": "Alt+H",
"chromeos": "Alt+H",
"linux": "Alt+H"
},
"description": "Toggle IHeader" // 描述
}
},
"content_scripts": [ // 随着每个页面加载的内容脚本,通过它可以访问到页面的DOM
{
"all_frames": false, // frame中不加载
"matches": ["\u003Call_urls>"], // 匹配所有URL
"js": ["res/js/message.js", "res/js/content.js"] // 内容脚本的路径
}
],
"default_locale": "en", // 默认语言
"description": "__MSG_description__", // 扩展描述
"manifest_version": 2, // Chrome 18及更高版本中,应该指定为2,低于v18版本的Chrome浏览器可以指定为1或不指定
"minimum_chrome_version": "26.0", // 最低支持到v26版本,主要受制于chrome.runtime api
"options_page": "res/options.html", // 选项页面的路径
"permissions": [ "tabs" , "webRequest", "webRequestBlocking", "http://*/*", "https://*/*", "contextMenus", "notifications"] // 扩展需要的权限
}Chrome Extension简介开始开发之前,我们先来刷一波基础知识。 Chrome官方明确规定了插件、扩展和应用的区别:
不注意区分的话,我们讲到Chrome插件,往往指的就是以上三者之一。为了避免引起误解,本篇将严格区分概念,避免使用插件这种含糊的说法。 如何安装扩展开发扩展,首先得从安装开始,从Chrome 21起,Chrome浏览器就增加了对扩展安装的限制,默认只允许从 Chrome Web Store (Chrome 网上应用店)安装扩展和应用,这意味着用户一般只能安装Chrome Web Store内的扩展和应用。 如果你拖动一个crx安装文件到Chrome浏览器的任何一个普通网页,将会出现如下提示。
点击
如果你恰好在Github上发现一个不错的Chrome扩展程序,而Chrome Web Store中没有。是不是就没有办法安装呢?当然不是的,Chrome浏览器还有三种其它的方式可以加载扩展程序。
2)点击添加扩展程序
3)添加好的扩展如下所示。
说到安装,自然有人会问,安装了某款扩展后,怎么查看该扩展的源码呢?Mac系统的用户请记住这个目录 扩展打包和更新另外,中间的
打包好的扩展程序,可以发送给其他人安装,或发布到Chrome Web Store(开发者注册费用为5$)。 右边的 扩展的基本组成通常一个Chrome扩展包含如下资源或目录:
为了方便管理,个人倾向于将HTML、JS、CSS,ICON等资源分类统一到同一个目录。 扩展的分类从使用场景上看,Chrome扩展可分为以下三类: 1)Browser Action,浏览器扩展,可通过manifest.json中的 "browser_action": {
"default_title": "Qrcode",
"default_icon": "images/icon.png",
"default_popup": "index.html" // 可选的
},以上是URL生成二维码的Browser Action扩展,运行如下所示:
该类扩展特点:全局扩展,icon长期占据浏览器右上角工具栏,每个页面均可用。 2)Page Action,页面级扩展,可通过manifest.json中的 "page_action": {
"default_title": "IHeader",
"default_icon": "res/images/lightning_default.png",
"default_popup": "res/index.html" // 可选的
},以上是本篇将要讲解的Page Action的扩展——IHeader,它被指定为所有页面可见,其icon状态切换如下所示。
该类扩展特点:不同页面可以拥有不同的状态和不同的icon,icon在指定的页面可见,可见时位于浏览器右上角工具栏。 由上可见,Browser Action与Page Action功能上非常相似,配置上各自的内部属性也完全一致,它们不仅可以配置点击时弹出的页面,同时还可以绑定点击事件,如下所示。 // 以下事件绑定一般在background.js中运行
// Browser Action
chrome.browserAction.onClicked.addListener(function(tab) {
console.log(tab.id, tab.url);
chrome.tabs.executeScript(tab.id, {file: 'content.js'});
});
// Page Action
chrome.pageAction.onClicked.addListener(function(tab) {
console.log(tab.id, tab.url);
});如果非要说两者的差别,开发中能够感受到的就是:前者不需要维护icon状态,后者需要针对每个启用的页面管理不同的icon状态。 3)Omnibox,全能工具条,可通过manifest.json中的 "omnibox": {
"keyword": "mdn-" //URL地址栏输入关键字"mdn-"+空格后,就会触发Omnibox
},以上是MDN网站快捷查询的Omnibox扩展,运行如下所示:
很明显,你可以对地址栏的各种输入做定制,Chrome的URL地址栏只所以强大,omnibox可谓功不可没。 该类扩展特点:运行在URL地址栏,无弹出界面,用户在输入时,扩展就可以显示建议或者自动完成一些工作。 以上三类决定了扩展如何在浏览器中运行。除此之外,每个扩展程序还可以任意搭载如下页面或脚本。
|
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|