Coachee (Forked from penpal) is a promise-based library for securely communicating with iframes via postMessage. The parent window can call methods exposed by iframes, pass arguments, and receive a return value. Similarly, iframes can call methods exposed by the parent window, pass arguments, and receive a return value. Easy peasy.
The total size of the library is approximately 5 KB minified and 2 KB gzipped. It has no dependencies.
Preferably, you'll be able to use Coachee from npm with a bundler like Browserify or webpack. If you use npm for client package management, you can install Coachee with:
npm install coachee --save
And import Coachee into your code with something like:
import Coachee from 'coachee';
Coachee provides a types
file for usage with TypeScript; importing is simply the same as above.
TODO
import Coachee from 'coachee';
const connection = Coachee.connectToChild({
// URL of page to load into iframe.
url: 'http://example.com/iframe.html',
// Container to which the iframe should be appended.
appendTo: document.getElementById('iframeContainer'),
// Methods parent is exposing to child
methods: {
add(num1, num2) {
return num1 + num2;
}
}
});
connection.promise.then(child => {
child.multiply(2, 6).then(total => console.log(total));
child.divide(12, 4).then(total => console.log(total));
});
import Coachee from 'coachee';
const connection = Coachee.connectToParent({
// Methods child is exposing to parent
methods: {
multiply(num1, num2) {
return num1 * num2;
},
divide(num1, num2) {
// Return a promise if the value being returned requires asynchronous processing.
return new Promise(resolve => {
setTimeout(() => {
resolve(num1 / num2);
}, 1000);
});
}
}
});
connection.promise.then(parent => {
parent.add(3, 1).then(total => console.log(total));
});
options.url
(required) The URL of the webpage that should be loaded into the iframe that Coachee will create. A relative path is also supported.
options.iframe
(optional) The iframe element. It would be querySelector string or a htmlElement Object. If not provided, would create one new by default.
options.appendTo
(optional) The element to which the created iframe should be appended. If not provided, the iframe will be appended to document.body
. If set options.iframe
, this not work.
options.methods
(optional) An object containing methods which should be exposed for the child iframe to call. The keys of the object are the method names and the values are the functions. If a function requires asynchronous processing to determine its return value, make the function immediately return a promise and resolve the promise once the value has been determined.
options.timeout
(optional) The amount of time, in milliseconds, Coachee should wait for the child to respond before rejecting the connection promise. There is no timeout by default.
The return value of connectToChild
is a connection
object with the following properties:
connection.promise
A promise which will be resolved once communication has been established. The promise will be resolved with an object containing the methods which the child has exposed. Note that these aren't actual memory references to the methods the child exposed, but instead proxy methods Coachee has created with the same names and signatures. When one of these methods is called, Coachee will immediately return a promise and then go to work sending a message to the child, calling the actual method within the child with the arguments you have passed, and then sending the return value back to the parent. The promise you received will then be resolved with the return value.
connection.destroy
A method that, when called, will remove the iframe element from the DOM and disconnect any messaging channels. You may call this even before a connection has been established.
connection.iframe
The child iframe element. The iframe will have already been appended as a child to the element defined in options.appendTo
, but a reference to the iframe is provided in case you need to add CSS classes, etc.
options.parentOrigin
(optional) The origin of the parent window which your iframe will be communicating with. If this is not provided, communication will not be restricted to any particular parent origin resulting in any webpage being able to load your webpage into an iframe and communicate with it.
options.methods
(optional) An object containing methods which should be exposed for the parent window to call. The keys of the object are the method names and the values are the functions. If a function requires asynchronous processing to determine its return value, make the function immediately return a promise and resolve the promise once the value has been determined.
options.timeout
(optional) The amount of time, in milliseconds, Coachee should wait for the parent to respond before rejecting the connection promise. There is no timeout by default.
The return value of connectToParent
is a connection
object with the following property:
connection.promise
A promise which will be resolved once communication has been established. The promise will be resolved with an object containing the methods which the parent has exposed. Note that these aren't actual memory references to the methods the parent exposed, but instead proxy methods Coachee has created with the same names and signatures. When one of these methods is called, Coachee will immediately return a promise and then go to work sending a message to the parent, calling the actual method within the parent with the arguments you have passed, and then sending the return value back to the child. The promise you received will then be resolved with the return value.
connection.destroy
A method that, when called, will disconnect any messaging channels. You may call this even before a connection has been established.
Setting Coachee.Promise
to a Promise constructor provides Coachee with a promise implementation that it will use. If a promise implementation is not provided by the consumer, Coachee will attempt to use window.Promise
.
Setting Coachee.debug
to true
or false
enables or disables debug logging. Debug logging is disabled by default.
If the child iframe attempts to reconnect with the parent, the parent will accept the new connection. This could happen, for example, if a user refreshes the child iframe or navigates within the iframe to a different page that also uses Coachee. In this case, the child
object the parent received when the initial connection was established will be updated with the new methods provided by the child iframe.
NOTE: Currently there is no API to notify consumers of a reconnection. If this is important for you, please file an issue and explain why it would be beneficial to you.
Coachee will throw (or reject promises with) errors in certain situations. Each error will have a code
property which may be used for programmatic decisioning (e.g., do something if the error was due to a connection timing out) along with a message
describing the problem. Errors may be thrown with the following codes:
Coachee.ERR_CONNECTION_DESTROYED
connection.promise
will be rejected with this error if the connection is destroyed (by callingconnection.destroy()
) while Coachee is attempting to establish the connection.- This error will be thrown when attempting to call a method on
child
orparent
objects and the connection was previously destroyed.
Coachee.ERR_CONNECTION_TIMEOUT
connection.promise
will be rejected with this error after thetimeout
duration has elapsed and a connection has not been established.
Coachee.ERR_NOT_IN_IFRAME
- This error will be thrown when attempting to call
Coachee.connectToParent()
from outside of an iframe context.
- This error will be thrown when attempting to call
While these error codes are on the Coachee object itself, they are also named exports. You may import them as follows:
import {
ERR_CONNECTION_DESTROYED,
ERR_CONNECTION_TIMEOUT,
ERR_NOT_IN_IFRAME
} from 'coachee';
This provides an opportunity for build optimization (using tools like Webpack or Rollup) in cases where code only needs access to the error constants and not the rest of Coachee.
Coachee is designed to run successfully on the most recent versions of Internet Explorer, Edge, Chrome, Firefox, and Safari.
This library is inspired by:
Thanks for penpal
MIT