Channels ▼
RSS

Mobile

Writing Chrome Extensions


Using a Callback

To navigate the user's currently selected tab to a new URL, the current tab's ID is acquired (using chrome.tabs.getSelected()) and then that tab is directed to the new URL using chrome.tabs.update(). A synchronous getSelected() could be written as below:

var tab = chrome.tabs.getSeleceted(null); // WRONG
chrome.tabs.update(tab.id, {url:"http://abc.com"});
……………………………
// THIS CODE DOESN'T WORK

This approach fails because getSelected() is asynchronous. It returns without waiting for its work to complete, and it doesn't even return a value (although some asynchronous methods do). getSelected(), or any method in general, is identified as asynchronous by the presence of the callback parameter in its signature. For example: chrome.tabs.getSelected(integer windowId, function callback).

The following code shows how to define a callback function that gets the results from getSelected() (as a parameter named tab) and calls update().

chrome.tabs.getSeleceted(null, function(tab){
chrome.tabs.update(tab.id, {url:"http://abc.com"});
……………………………….
});
//THIS CODE WORKS FINE

The callback function specified to getSelected is called only after information about the currently selected tab is available, which is sometime after getSelected() returns. Also note that although update() is asynchronous, this example doesn't use its callback parameter, as we don't do anything with the results of the update.

Cross-Origin XMLHttpRequest

Extensions can interact with the outside world using XMLHttpRequest objects available in JavaScript. Unlike regular Web pages, which can use XMLHttpRequest to send and receive data from remote servers, but are limited by the same origin policy, extensions aren't limited this way. An extension can talk to remote servers outside of its origin as long as it has requested cross-origin permissions in its definition.

Extension Origin

Each running extension exists within its own separate security origin. Without requesting additional privileges, the extension can use XMLHttpRequest to get resources within its installation. For example, if an extension contains a text file "abc.txt," the extension can retrieve the file's contents as shown in the following code. var xmlUnameRequest = new XMLHttpRequest(); var url = "/abc.txt"; xmlUnameRequest.open("GET", url, true); xmlUnameRequest.onreadystatechange = handler; xmlUnameRequest.send(null); function handler(evtXHR){ if (xmlhttp.readyState == 4&&xmlhttp.status == 200) { alert(xmlhttp.responseText); } else { alert("Error "+xmlhttp.status); } }

If the extension attempts to use a security origin other than itself, say http://www.google.com, the browser disallows it unless the extension has requested the appropriate cross-origin permissions.The same permission can be made available to the extension by specifying those host names in the manifest file as below.

{
"name" : "Kz_Face_Lift",
"permissions":[
   http://www.google.com/,
   http://*/*,
   https://*/
  ]
}

A match pattern of http://*/* allows HTTP access to all reachable domains. Match patterns are similar to content script match patterns, but any path information following the host is ignored. Access is granted both by host and by scheme. If an extension wants both secure and non-secure HTTP access to a given host or set of hosts, the permissions must be declared separately with https and http as in the aforementioned example. While using an XMLHttpRequest object in the plugin pages, you can pass the destination URL (http://www.mysite.com/getData) after ensuring the same was specified in the manifest file.

Packaging and Deployment

To deploy the extension, the contents of the folder can be packaged into a special ZIP file that has a .crx suffix.

  1. Bring up the extensions management page by going to the following URL: chrome://extensions
  2. Go to Developer Mode and Click the pack extension button. A dialog appears.
  3. In the extension root directory field, specify the path to the extension's folder — for example, c:\myext. (Ignore the other field; you don't specify a private key file the first time you package a particular extension.)
  4. Click OK. The packager creates two files: a .crx file, which is the actual extension that can be installed; and a .pem file, which contains the private key.
  5. The .crx file can be hosted on a Web server for the end users to download onto their Chrome browsers.

The .pem file must update the extension and upload the extension to the Chrome Web Store. On successful packaging of the extension, a dialog box is displayed providing the information regarding the location of .crx and .pem files. (Figure 1.)


Figure 1.

Packaging also can be done at the command line by specifying the folder where the plugin resides; and upon successful packaging, the same dialog box will pop up.

chrome.exe --pack-extension= C:\KzExtension\Kz_FaceLift

Hosting

The Web server that hosts .crx files must use appropriate HTTP headers, so that end users can install the file onto their browsers by clicking a link to it. Google Chrome considers a file to be installable if the file has the content type application/x-chrome-extension or the file suffix is .crx and both of the following are true: The file is not served with the HTTP header X-Content-Type-Options: nosniff option, and it is served with one of these content types:

  • empty string
  • "text/plain"
  • "application/octet-stream"
  • "unknown/unknown"
  • "application/unknown"
  • "*/*"

The most common reason for failing to recognize an installable file is that the server sends the header XContent-Type-Options: nosniff. The second most common reason is that the server sends an unknown content type — one that isn't in the previous list. To fix an HTTP header issue, either change the configuration of the server or try hosting the .crx file on another server.

With this introduction, you should be well on your way to building fun and useful extensions to Chrome.

Useful References

Google Chrome Extensions Tutorial: Getting Started (Hello, World!)

JSON Wikipedia page

chrome.* APIs

XMLHttpRequest Level 2, W3C Working Draft 17, January 2012


— Kausar Munshi works as a developer in Java and Web Technologies. Basavaraju graduated from IIT Madras and has approximately 15 years of experience in IT.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video