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. SuSe Linux 10 企业服务器搭建双机集群配置实例

      650) this.width=650;" onclick="window.open("http://blog.51cto.com/viewpic.php?refim ...

  2. httpurlconnection发送文件到服务端并接收

    httpurlconnection发送文件到服务端并接收 客户端 import java.io.DataInputStream; import java.io.File; import java.io ...

  3. 关于Webpack详述系列文章 (第三篇)

    1. 类图 1. 模块 Module是webpack中最核心的类,要加载定的一切和依赖都是Module. 它有很多子类 RawModule NormalModule MultiModule Conte ...

  4. C#监控代码运行的时间

    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); //开始监视代码运行时间 ...

  5. BZOJ2631: tree(LCT)

    Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2 ...

  6. python处理文件

    打开文件:     open是内建函数,一个方法 open("test.txt","r",buffering=1) test.txt 表示被打开的文件名,如果不 ...

  7. <link rel="shortcut icon" href="Xubuntu.ico" type="image/x-icon" /> <LINK href="Xubuntu.ico" rel="shortcut icon"> <link href="Xubuntu.ico" rel="B

    <link rel="shortcut icon" href="Xubuntu.ico" type="image/x-icon" /& ...

  8. C#与C++ DLL的交互

    C#与C++交互,总体来说可以有两种方法: 1.利用C++/CLI作为代理中间层 2.利用PInvoke实现直接调用   第一种方法:实现起来比较简单直观,并且可以实现C#调用C++所写的类,但是问题 ...

  9. HDU1203 I NEED A OFFER! 【贪心】

    I NEED A OFFER! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  10. 1. 初识ZooKeeper。

    转自:https://blog.csdn.net/en_joker/article/details/78661466 Apache ZooKeeper是由 Apache Hadoop的子项目发展而来, ...