Giter VIP home page Giter VIP logo

post-robot's Introduction

post-robot [:]-\-<

Cross domain post-messaging on the client side, using a simple listener/client pattern.

Send a message to another window, and:

Simple listener and sender with error handling

postRobot.on('getUser', function(event) {
    return {
        id:   event.data.id,
        name: 'Zippy the Pinhead'
    };
});
postRobot.send(someWindow, 'getUser', { id: 1337 }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

Listener with promise response

postRobot.on('getUser', function(event) {

    return getUser(event.data.id).then(function(user) {
        return {
            name: user.name
        };
    });
});

Listener with callback response

postRobot.on('getUser', { id: 1337 }, function(event, callback) {

    setTimeout(function() {
        callback(null, {
            id:   event.data.id,
            name: 'Captain Pugwash'
        });
    }, 500);
});

One-off listener

postRobot.once('init', function(event) {

    return {
        name: 'Noggin the Nog'
    };
});

Listen for messages from a specific window

postRobot.on('init', { window: window.parent }, function(event) {

    return {
        name: 'Guybrush Threepwood'
    };
});

Listen for messages from a specific domain

postRobot.on('init', { domain: 'http://zombo.com' }, function(event) {

    return {
        name: 'Manny Calavera'
    };
});

Set a timeout for a response

postRobot.send(someWindow, 'getUser', { id: 1337 }, { timeout: 5000 }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

Send a message to a specific domain

postRobot.send(someWindow, 'getUser', { id: 1337 }, { domain: 'http://zombo.com' }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);
});

Send a message to the direct parent

postRobot.sendToParent('getUser').then(function(event) {
    console.log(event.data);
});

Async / Await

postRobot.on('getUser', async ({ source, origin, data }) => {

    let user = await getUser(data.id);

    return {
        id:   data.id,
        name: user.name
    };
});
try {
    let { source, origin, data } = await postRobot.send(someWindow, `getUser`, { id: 1337 });
    console.log(source, origin, 'Got user:', data.name);

} catch (err) {
    console.error(err);
}

Secure Message Channel

For security reasons, it is recommended that you always explicitly specify the window and domain you want to listen to and send messages to. This creates a secure message channel that only works between two windows on the specified domain:

postRobot.on('getUser', { window: childWindow, domain: 'http://zombo.com' }, function(event) {
    return {
        id:   event.data.id,
        name: 'Frodo'
    };
});
postRobot.send(someWindow, 'getUser', { id: 1337 }, { domain: 'http://zombo.com' }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

You can even set up a listener and sender instance in advance:

var listener = postRobot.listener({ window: childWindow, domain: 'http://zombo.com' });

listener.on('getUser', function(event) {
    return {
        id:   event.data.id,
        name: 'Frodo'
    };
});
var client = postRobot.client({ window: someWindow, domain: 'http://zombo.com' });

client.send('getUser', { id: 1337 }).then(function(event) {
    console.log(event.source, event.origin, 'Got user:', event.data.name);

}).catch(function(err) {
    console.error(err);
});

Functions

Post robot lets you send across functions in your data payload, fairly seamlessly.

For example:

postRobot.on('getUser', function(event) {
    return {
        id:     event.data.id,
        name:   'Nogbad the Bad',

        logout: function() {
            currentUser.logout();
        }
    };
});
postRobot.send(myWindow, { id: 1337 }, 'getUser').then(function(event) {
    var user = event.data;

    user.logout().then(function() {
        console.log('User was logged out');
    });
});

The function user.logout() will be called on the original window. Post Robot transparently messages back to the original window, calls the function that was passed, then messages back with the result of the function.

Because this uses post-messaging behind the scenes and is therefore always async, user.logout() will always return a promise, and must be .then'd or awaited.

Parent to popup messaging

Unfortunately, IE blocks direct post messaging between a parent window and a popup, on different domains.

In order to use post-robot in IE9+ with popup windows, you will need to set up an invisible 'bridge' iframe on your parent page:

   [ Parent page ]

+---------------------+          [ Popup ]
|        xx.com       |
|                     |      +--------------+
|  +---------------+  |      |    yy.com    |
|  |    [iframe]   |  |      |              |
|  |               |  |      |              |
|  | yy.com/bridge |  |      |              |
|  |               |  |      |              |
|  |               |  |      |              |
|  |               |  |      |              |
|  |               |  |      +--------------+
|  +---------------+  |
|                     |
+---------------------+

a. Create a bridge path on the domain of your popup, for example http://yy.com/bridge.html, and include post-robot:

<!-- http://yy.com/bridge.html -->

<script src="http://yy.com/js/post-robot.js"></script>

b. In the parent page, xx.com, which opens the popup, include the following javascript:

<!-- http://xx.com -->

<script>
    postRobot.openBridge('http://yy.com/bridge.html');
</script>

c. Now xx.com and yy.com can communicate freely using post-robot, in IE.

post-robot's People

Contributors

bluepnume avatar mstuart avatar bryclee avatar christophior avatar

Watchers

James Cloos avatar Janis Reber avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.