voxmedia/iframe-client

Name: iframe-client

Owner: Vox Media

Description: Cross-origin iframe messaging client

Created: 2015-12-23 19:29:51.0

Updated: 2016-09-27 11:56:33.0

Pushed: 2015-12-29 19:53:04.0

Homepage:

Size: 31

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

IframeClient

Provides simple and reliable cross-origin JavaScript messaging between iframes and their host pages by wrapping window.postMessage in a transactional layer. IframeClient builds atop postMessage in the way that TCP builds atop IP. IframeClient provides request/response cycles with polling and timeouts to (better) guarentee that messages will be received and post back responses.

This repo is configured as an NPM module and a Ruby gem for integration into Node-based projects and Rails applications.

Install
Node

In package dependencies:

"iframe-client": "git@github.com:voxmedia/iframe-client.git"

Then install:

npm install

In project script:

var IframeClient = require('iframe-client');

Rails

In Gemfile:

gem 'iframe-client', :git => 'git@github.com:voxmedia/iframe-client.git'

In JavaScript manifest:

//= require iframe-client

Usage
1. Create client instances

First, create a new IframeClient instance on your host page and within each iframe window:

On http://my-host-page.com/index.html

hostClient = IframeClient.create('myapp', 'http://my-embed.com');

On http://my-embed.com/embed.html

embedClient = IframeClient.create('myapp', '*');

The IframeClient.create factory function accepts an application namespace and a frame origin that the new client may post messages to. It's very important that each window (host and iframes) build their own client instance with a common namespace so they may respond to relevant messages within their window environment.

2. Configure message handlers

Next, configure each client with the messages that it should respond to. Message handlers may be chained using calls to the .on() method. A handler function receives the message event and a payload of data from each message, and may return response data to pass back to the sender. After configuring all message handlers, call .listen() to begin monitoring communication.

dClient
n('play', function(evt, data) { ... })
n('pause', function(evt, data) { ... })
n('getstuff', function(evt, data) { return 'stuff' })
isten();
3. Send messages

Messages may be posted or requested.

Using post, a client sends a one-time message attempt to the target window. This message is posted blindly at the target window, and provides no indication as to whether the message was actually received. Message posts will commonly fail if one window starts sending messages before another window is ready to receive them.

Client.post('#my-iframe', 'play', 'hello embed!');

Using request, a client initiates a full request/response cycle with the target window. A request will repeatedly send a message to the target window, and does not stop sending until the target responds or the request times out. This also allows windows to coordinate data passing, and for completed requests to trigger callbacks.

Client.request('#my-iframe', 'getstuff', 'hello embed!', function(err, res) {
 (err) return console.log(err.message);
nsole.log('Received response:', res);

API
IframeClient.isInIframe()

Checks if the current window environment is displayed in an iframe. Returns true when in an iframe.

var cli = IframeClient.create(appId, [allowedOrigin])

Creates a new IframeClient instance.

cli.on(message, handler, [context])

Registers a message handler on the client. Handlers will run when the specified message type is received within the window. Returns the client instance to support method chaining.

cli.listen()

Starts the client listening for incoming messages. Call this once after registering all message handlers. Returns the client instance to support method chaining.

cli.post(target, message, [value])

Posts a blind message to another window. This is a convenience wrapper for calling postMessage with some added data management. Messages sent via post may fail if the receiving window's client has not yet fully initialized. Use this method to send non-critical messages where loss is acceptible.

cli.request(target, message, [value], [callback])

Initiates a request/response cycle with the target window. The message is repeatedly sent to the target window until the window responds, or until the request times out. Use this method for better guarentee of critical message delivery, or to request a data response from another window.

cli.dispose()

Stops listening and cancels all polling messages. Releases the client for garbage collection.

Testing
install
test

Or, open test/test.html in a browser after package installation.

Contributing
  1. Fork it ( https://github.com/voxmedia/iframe-client/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.