How to Make a Chrome Extension.

https://robots.thoughtbot.com/how-to-make-a-chrome-extension

Skip to main content

How to Make a Chrome Extension

January 23, 2015 UPDATED ON December 1, 2015

If you’re wondering how to make a Chrome Extension, Chrome’s extension documentation is great for basic implementations. However, to use more advanced features requires a lot of Googling and Stack Overflow. Let’s make an intermediate Chrome extension that interacts with the page: it will find the first external link on the page and open it in a new tab.

manifest.json

The manifest.json file tells Chrome important information about your extension, like its name and which permissions it needs.

The most basic possible extension is a directory with a manifest.json file. Let’s create a directory and put the following JSON into manifest.json:

{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.1"
}

That’s the most basic possible manifest.json, with all required fields filled in. The manifest_version should always be 2, because version 1 is unsupported as of January 2014. So far our extension does absolutely nothing, but let’s load it into Chrome anyway.

Load your extension into Chrome

To load your extension in Chrome, open up chrome://extensions/ in your browser and click “Developer mode” in the top right. Now click “Load unpacked extension…” and select the extension’s directory. You should now see your extension in the list.

When you change or add code in your extension, just come back to this page and reload the page. Chrome will reload your extension.

Content scripts

content script is “a JavaScript file that runs in the context of web pages.” This means that a content script can interact with web pages that the browser visits. Not every JavaScript file in a Chrome extension can do this; we’ll see why later.

Let’s add a content script named content.js:

// content.js
alert("Hello from your Chrome extension!")

To inject the script, we need to tell our manifest.json file about it.

Add this to your manifest.json file:

"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["content.js"]
}
]

This tells Chrome to inject content.js into every page we visit using the special <all_urls> URL pattern. If we want to inject the script on only some pages, we can use match patterns. Here are a few examples of values for "matches":

  • ["https://mail.google.com/*", "http://mail.google.com/*"] injects our script into HTTPS and HTTP Gmail. If we have / at the end instead of /*, it matches the URLs exactly, and so would only inject into https://mail.google.com/, not https://mail.google.com/mail/u/0/#inbox. Usually that isn’t what you want.
  • http://*/* will match any http URL, but no other scheme. For example, this won’t inject your script into https sites.

Reload your Chrome extension. Every single page you visit now pops up an alert. Let’s log the first URL on the page instead.

Logging the URL

jQuery isn’t necessary, but it makes everything easier. First, download a version of jQuery from the jQuery CDN and put it in your extension’s folder. I downloaded the latest minified version, jquery-2.1.3.min.js. To load it, add it to manifest.json before "content.js". Your whole manifest.json should look like this:

{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.1",
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-2.1.3.min.js", "content.js"]
}
]
}

Now that we have jQuery, let’s use it to log the URL of the first external link on the page in content.js:

// content.js
var firstHref = $("a[href^='http']").eq(0).attr("href"); console.log(firstHref);

Note that we don’t need to use jQuery to check if the document has loaded. By default, Chrome injects content scripts after the DOM is complete.

Try it out - you should see the output in your console on every page you visit.

Browser Actions

When an extension adds a little icon next to your address bar, that’s a browser action. Your extension can listen for clicks on that button and then do something.

Put the icon.png from Google’s extension tutorial in your extension folder and add this to manifest.json:

"browser_action": {
"default_icon": "icon.png"
}

In order to use the browser action, we need to add message passing.

Message passing

A content script has access to the current page, but is limited in the APIs it can access. For example, it cannot listen for clicks on the browser action. We need to add a different type of script to our extension, a background script, which has access to every Chrome API but cannot access the current page. As Google puts it:

Content scripts have some limitations. They cannot use chrome.* APIs, with the exception of extensioni18nruntime, and storage.

So the content script will be able to pull a URL out of the current page, but will need to hand that URL over to the background script to do something useful with it. In order to communicate, we’ll use what Google calls message passing, which allows scripts to send and listen for messages. It is the only way for content scripts and background scripts to interact.

Add the following to tell manifest.json about the background script:

"background": {
"scripts": ["background.js"]
}

Now we’ll add background.js:

// background.js

// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
// Send a message to the active tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
});
});

This sends an arbitrary JSON payload to the current tab. The keys of the JSON payload can be anything, but I chose "message" for simplicity. Now we need to listen for that message in content.js:

// content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action" ) {
var firstHref = $("a[href^='http']").eq(0).attr("href"); console.log(firstHref);
}
}
);

Notice that all of our previous code has been moved into the listener, so that it is only run when the payload is received. Every time you click the browser action icon, you should see a URL get logged to the console. If it’s not working, try reloading the extension and then reloading the page.

Opening a new tab

We can use the chrome.tabs API to open a new tab:

chrome.tabs.create({"url": "http://google.com"});

But chrome.tabs can only be used by background.js, so we’ll have to add some more message passing since background.js can open the tab, but can’t grab the URL. Here’s the idea:

  1. Listen for a click on the browser action in background.js. When it’s clicked, send a clicked_browser_action event to content.js.
  2. When content.js receives the event, it grabs the URL of the first link on the page. Then it sends open_new_tab back to background.js with the URL to open.
  3. background.js listens for open_new_tab and opens a new tab with the given URL when it receives the message.

Clicking on the browser action will trigger background.js, which will send a message to content.js, which will send a URL back to background.js, which will open a new tab with the given URL.

First, we need to tell content.js to send the URL to background.js. Changecontent.js to use this code:

// content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action" ) {
var firstHref = $("a[href^='http']").eq(0).attr("href"); console.log(firstHref); // This line is new!
chrome.runtime.sendMessage({"message": "open_new_tab", "url": firstHref});
}
}
);

Now we need to add some code to tell background.js to listen for that event:

// background.js

// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
// Send a message to the active tab
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
});
}); // This block is new!
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "open_new_tab" ) {
chrome.tabs.create({"url": request.url});
}
}
);

Now when you click on the browser action icon, it opens a new tab with the first external URL on the page.

Wrapping it up

The full content.js and background.js are above. Here’s the full manifest.json:

{
"manifest_version": 2,
"name": "My Cool Extension",
"version": "0.1",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["jquery-2.1.3.min.js", "content.js"]
}
],
"browser_action": {
"default_icon": "icon.png"
}
}

And here’s the full directory structure:

.
├── background.js
├── content.js
├── icon.png
├── jquery-2.1.3.min.js
└── manifest.json

More on how to make a Chrome extension

For more information, try the official Chrome extension documentation.

 

Make chrome extension的更多相关文章

  1. Chrome Extension 检查视图(无效)处理方法

    最近闲来无事,简单看了下Chrome扩展的开发,并且开发一个小小的翻译插件(TranslateBao)作为练手,开发细节不详述了,如果有新学习chrome extension开发的新人,可以参考源码, ...

  2. 开发Chrome Extension截取你微博的帐号密码

    Google允许开发者对Chrome浏览器做扩展,所以有了之前火爆的12306抢票软件,我 也用它抢过票,一直很好奇它怎么注入js到12306上面的.这周有空研究了下Chrome Extension, ...

  3. chrome extension overview

    目录 什么是扩展............................................................................................ ...

  4. 打包Egret游戏为Chrome extension

    今天,本来是打算做一个Chrome扩展去爬取网站base64编码图片的. 在跟着图灵社区<Chrome扩展及应用开发>敲demo代码的过程中,发现chrome的扩展的结构理论上可以兼容所有 ...

  5. Google Chrome Native Messaging开发实录(二)Chrome Extension扩展

    接上一篇<Google Chrome Native Messaging开发实录(一)背景介绍>的项目背景,话不多说,有关Chrome Extension介绍和文档就不展开了,直接上代码. ...

  6. Chrome Extension 实战

    想起个问题,线上项目js要有bug,怎么进行调试修改. ------------- 想起来,方法应该是,拦截线上的js的请求,转到本地代码上进行调试... ------------- 网上看到 Chr ...

  7. 解决chrome extension无法下载的问题

    由于GFW把谷歌应用商店给屏蔽了,下载chrome扩展变得很困难. 我使用的是版本30.0.1599.101 m. 那么你需要做的第一个处理是,修改host文件,保证chrome应用商店可以登录.如下 ...

  8. 一起来做Chrome Extension《搭个架子》

    CEF - A simple Chrome Extension development falsework CEF是一个简单的Chrome Extension开发脚手架,它有如下功能: 模块化的结构, ...

  9. 一起来做Chrome Extension《一些问题》

    目录 Unchecked runtime.lastError: The message port closed before a response wa received. 使用 eval Conte ...

  10. chrome extension demos

    chrome extension demos demo https://github.com/hartleybrody/buzzkill/blob/master/bootstrap.js https: ...

随机推荐

  1. 公众平台调整SSL安全策略,请开发者注意升级

    公众平台调整SSL安全策略,请开发者注意升级 近一段时间HTTPS加密协议SSL曝出高危漏洞,可能导致网络中传输的数据被黑客监听,对用户信息.网络账号密码等安全构成威胁.为保证用户信息以及通信安全,微 ...

  2. 数组-reduce方法

    转自: https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/139 实现 convert 方法,把原始 list ...

  3. BZOJ2780: [Spoj]8093 Sevenk Love Oimaster(广义后缀自动机,Parent树,Dfs序)

    Description Oimaster and sevenk love each other. But recently,sevenk heard that a girl named ChuYuXu ...

  4. C语言之函数指针、回调函数的使用

    一.背景 首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义. typedef void (PUBLI ...

  5. eclipse git冲突解决

    1.工程->Team->同步: 2.从远程pull至本地,就会出现如下内容: 3.使用Merge Tool,执行第二项 4.再手动修改 4.修改后的文件需要添加到Git index中去: ...

  6. ToggleButton控件

    ToggleButton 两种状态 ·状态button     -继承自CompoundButton ·主要属性:-Android:textOn    -Android:textOff ·主要方法: ...

  7. 86.八千万qq密码按相似度排序并统计密码出现次数,生成密码库

    存储qq的文件地址以及按照密码相似度排序的文件地址 //存储qq的文件的地址 ] = "QQ.txt"; //按照密码相似度排序的文件地址 ] = "QQpassword ...

  8. Thinkphp5创建控制器

    今天我们就来创建一个控制器: <?php namespace app\index\controller; use think\Controller; class Test extends Con ...

  9. 语音识别系统:有免费实用的"语音到文字"的软件么?

    自从看了<李开复自传>,就对"语音识别系统"产生了非常深刻的印象. 根据自己的判断,语音识别系统还是非常有用的. 以自己的实际需求来看: 1.中国象棋中的应用. 中国象 ...

  10. 洛谷——P1046 陶陶摘苹果

    https://www.luogu.org/problem/show?pid=1046 题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有 ...