Giter VIP home page Giter VIP logo

porthole's Introduction

Porthole is a small library for secure cross-domain iFrame communication.

Usage

Include the Javascript.

<script type="text/javascript" src="porthole.min.js"></script>

Create your content iFrame. This is where the guest content lives. Make sure to give it a name.

<iframe id="guestFrame" name="guestFrame" src="http://other-domain.com/">
</iframe>

Define an event handler if you want to receive messages.

function onMessage(messageEvent) {  
    /*
   messageEvent.origin: Protocol and domain origin of the message
   messageEvent.data: Message itself
   messageEvent.source: Window proxy object, useful to post a response 
   */
}

Create a window proxy object on the main page.

var windowProxy;
window.onload=function(){ 
    // Create a proxy window to send to and receive 
    // messages from the iFrame
    windowProxy = new Porthole.WindowProxy(
        'http://other-domain.com/proxy.html', 'guestFrame');

    // Register an event handler to receive messages;
    windowProxy.addEventListener(onMessage);
};

Create a window proxy object in the iFrame.

var windowProxy;
window.onload=function(){ 
    // Create a proxy window to send to and receive 
    // messages from the parent
    windowProxy = new Porthole.WindowProxy(
        'http://parent-domain.com/proxy.html');

    // Register an event handler to receive messages;
    windowProxy.addEventListener(function(event) { 
        // handle event
    });
};

Send a message.

windowProxy.post({'action': 'supersizeme'});

Note that if you have multiple iFrames, you can create as many WindowProxy objects as needed.

Update

The library has been updated. It is not compatible with previous versions.

  • Support JSON serialization
  • Bug fix for IE 8
  • Bug fix for multiple event handler in native browser support.

Unit Tests

rake jasmine

Demo

http://sandbox.ternarylabs.com/porthole/

Project Page

http://ternarylabs.github.com/porthole/

porthole's People

Contributors

andreineculau avatar georges avatar hachibu avatar isakb avatar lutangar avatar zmonteca avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

porthole's Issues

mixed-mode environment

Is this going to work in an mixed mode environment? I mean the main page in HTTPS and the guest in HTTP. Is there a way to make this (iframe) to work in a mixed-mode environment?

Do a windowProxy.post when the page loads

I'm trying to get data from localStorage and send it to the guest when the page loads but it doesn't works, any workaround or solution?

(function($){
  windowProxy.post({'html' : localStorage.getItem('htmlDB') });
})(jQuery);

issue more detailed here

Allow setting event type when posting a message

Right now all events being dispatched just have an event type of "message". It would be great if you could optionally control the type when posting a message. This would with creating multiple handlers that just care about specific types of messages.

something like
postMessage(message, [options])

possible options {type: "closeFrame"}

Using porthole in an iframe

Hi,

I'm currently faced to the problem that I have to use porthole in an iframe. It seems like porthole gets lost if I try to communicate with iframes in that iframe. Here is an example:

<body>
  <div style="width:100%;height:600px; background-color: #009">
   <iframe src="http://localhost/portholeDemos/sandbox.ternarylabs.com/porthole/" style="height:400px; width:100%; background-color: #fff"></iframe>
 </div>
</body>

Is there any solution to get porthole working out of an iframe? the example above includes the official example of your repository.

Is this case possible?

Release on npm

Would be nice to have porthole available through npm.

No works in Angualr2 or >

Hello,
i was trying to impelemt in my angular2 app but its no works. i can initialize de portHole object but the listener never is called.

    var windowProxy;
    windowProxy = new Porthole.WindowProxy('', 'iframeSrc');
    // Register an event handler to receive messages;
    // if (window.addEventListener) {
    //     window.addEventListener('message', this.handledMessage.bind(this), false);
    // } else {
    //      (<any>window).attachEvent('onmessage', this.handledMessage.bind(this));
    // }

    windowProxy.addEventListener((event: any) =>  {
        debugger;
    });

Any help please?

Iframe inside an Iframe

We have an application in which our clients launch our container app into an iframe. This iframe (call it the 'orchestrator') then can launch a number of applications within it via another iframe (call it a 'product'). At the moment, it seems that getTargetWindow is having an issue with my setup.

What we want to do is set up a communication proxy between product iframe and orchestrator iframe. At the moment, i have unilateral communication from product to orchestrator, but i cant seem to get orchestrator to product figured out.

Product Iframe talking to orchestrator (works):

var proxy = Porthole.WindowProxy('orchestratordomain/proxy.html`, 'parent');
proxy.post(message);

Orchestrator Iframe talking to product (doesnt):

var proxy = Porthole.WindowProxy('productdomain/proxy.html`, 'productFrameName');
proxy.post(message);

DOM Layout

When we get to getTargetWindow on line 384 for the scenario that doesnt work is targetWindowName thats being sent in is productFrameName that we do a parent.frames['productFrameName']; which is null since the parent.frames is essentially pointing to the http://clientapp.com location which doesnt have the productFrameName in it.

I updated the else if on line 381 to do || window[targetWindowName] which for my scenario DOES find 'productFrameName' but when i try and post a message to it, my event handlers are not firing.

So there could really be two different things going on here:

  • Porthole doesnt support iFrame communication inside of an iFrame
  • My event handlers are jacked up

Whats weird is that it works from the product up to the orchestrator, but not from the orchestrator down. Im fairly new to how porthole works but would love some help if at all possible.

Here is a link to my public dropbox that essentially lays out what im talking about. I added this to a webserver and it failed on the same place its failing on it for me.
https://www.dropbox.com/s/0lu4y01zsbegbjx/test.html?dl=0

Any help would be greatly appreciated, especially if this is not a viable solution for our application as we are currently in the prototyping phase.

Thanks,

Jake

Porthole broken in IE 9

It seems that Porthole is broken in IE9 as I am getting the following error on the javascript console:

"No relay set (used as window.postMessage targetOrigin), cannot send cross-domain message"

My same code works fine in Chrome, which is the only other browser I've tested so far.
Interestingly, I am also seeing this log message from Porthole:
"Using legacy browser support"

I am not sure if it's the legacy support causing the problem or not, but when I run the following javascript:
alert((typeof window.postMessage);
I see:
"object"

So IE9 thinks window.postMessage is an object and not a function.
My testing was with IE 9.0.8112.x 64-bit Edition.

I hope this can be fixed soon, as Porthole is a very useful tool, and I'm a big fan of it.
:

race condition on porthole loading - how to handle ?

I've run into an issue with race conditions with Porthole.

My code does the following stuff to shuffle a centralized account system's login-status across a few domains.

Domain A

  1. JS writes Porthole JS & iFrame
  2. JS registers a 'ready()' event to set up the Porthole.WindowProxy
  3. Any Porthole calls are made through an 'ensureProxy' wrapper; it makes sure we have a Porthole.WindowProxy on the window.

Domain B ( controller )

  1. JS ( window.onload ) sets up an inbound Porthole.WindowProxy

After doing a lot of debugging, it seems that the problem is due to DomainA sending a request through the outbound WindowProxy before DomainB has set up the inbound WindowProxy.

I've got a temporary fix in place to handle this -- I defer outbound requests for an additional 5 seconds after the outbound WIndowProxy has been set up. That seems to catch most things ( though its not as slick as I'd like it to be ).

This package often confuses me at times ( it's great! it's just doing complex / confusing things !). I'm hoping someone here might have more experience with it to know if it's possible to fix this.

My initial thought was along the lines of having the OutboundProxy manage a 'ready' state. Once configured, the InboundProxy in controller.html file would send a 'ready' ping back to the OutboundProxy (which would then either change state and/or begin sending queued requests ). I'm not sure that is possible though.

In regards to why I'm using javascript -- it made the integration easier. I was already running into this problem though, as I needed to run the Porthole during the jquery ready() event. The 'normal' integration of Porthole has everything handled within window.onload , and the Outbound frame's javascript waits for the Inbound frame's ( controller.html ) javascript to fully load and execute. This works well when you have small page with few assets. When you have more assets , or allow 3rd party content , the window.onload event can take minutes to finally fire.

Both onMessage listeners get called for second example in chrome/FF

Hi,

The example code at http://sandbox.ternarylabs.com/porthole/ seems to have a bug.

When clicking expand/shrink on either iframe, both event handlers get called for each incoming message in FF5 & Chrome 12 and both iframes get resized. In IE9/8/7 it works fine.

I got it working in FF/Chrome by adding this

function onMessage1(messageEvent) {
var frame = document.getElementById('myiframe');
if (messageEvent.origin == "http://" + guestDomain && messageEvent.source === frame.contentWindow) {

Which checks the message source against the frame content window, however this breaks it in IE8/7.

Any ideas?

Many Thanks,

Ian

Help

How do i change the form action inside a iframe from the parent window? Please help!

Javascript Security Restrictions on Chrome Stable Break Porthole

Overview

Tested on OS: Linux / Windows XP
Browsers affected: Chrome Stable (10.0.648.205), Mozilla Firefox 3.5.16

This works for http://sandbox.ternarylabs.com/porthole/
This doesn't work for a freshly cloned repo

Problem Description

There are several issues here, but I believe them to be related so they're all being put in here.
Issue 1) When changing the colour of the child frames, the operation succeeds, but reports errors when trying to run forwardMessageEvent.
Issue 2) When changing the colour of the parent from a child frame, the operation fails. Errors are reported relating to security policy problems.

Steps to reproduce

Issue 1) Javascript errors for operations on the parent

  1. Checkout the porthole repo into the root of some webserver you control (git clone https://github.com/ternarylabs/porthole.git)
  2. Navigate to the content on Google Chrome stable, e.g. http://lateralus/porthole/porthole
  3. Click Color Frame1 Red

What happens?

  • The window color of the first frame is changed to red
  • The following is output on the console
    Porthole.WindowProxyDispatcher.findWindowProxyObjectInWindow
    Unsafe JavaScript attempt to access frame with URL http://lateralus/porthole/ from frame with URL http://demo.auberger.com/porthole/proxy.html#color=red&sourceOrigin=http%3A//lateralus&targetOrigin=*&sourceWindowName=&targetWindowName=guestFrame1. Domains, protocols and ports must match.
    Can't access object: top
    Can't access object: window
    Can't access object: location
    Can't access object: chrome
    Can't access object: external
    Can't access object: document
    Can't access object: Porthole
    

Expected:
No JS errors.

Issue 2) Javascript operations on the child

  1. Assuming you've already got a checkout of the page, and have navigated to the root directory of the checked out repo, click the 'Color Parent Blue' button on Frame1.

What happens?

  • No changes occur on the parent
  • The following is output on the console
    Porthole.WindowProxyDispatcher.forwardMessageEvent
    Porthole.WindowProxyDispatcher.findWindowProxyObjectInWindow
    (x2) Unsafe JavaScript attempt to access frame with URL http://lateralus/porthole/ from frame with URL http://sandbox.ternarylabs.com/porthole/proxy.html#color=green&sourceOrigin=http%3A//demo.auberger.com&targetOrigin=*&sourceWindowName=guestFrame1&targetWindowName=. Domains, protocols and ports must match.
    Could not find window proxy object on the target window
    

Expected:
No JS errors. Parent frame changes colour.

why specify url when creating Porthole.windowProxy? Seems to do fine without

When rendering an Iframe as per the docs I need to pass the url of the parent window as so:
windowProxy = new Porthole.WindowProxy( 'http://other-domain.com/proxy.html');

However, bc. of limitations of my server setup it's kind of a hack to get the variable url of the parent window on the server.

Therefore, I tried doing the following which just seems to work:
windowProxy = new Porthole.WindowProxy();

So, what would be the reason for having to pass the url of the parent window if any?

Not working on IE8!

Hi Guys,

I have spent the last hours trying to understand why my code that is using Porthole wasn't working on the website of a client and found out they were forcing IE8 compatibility mode. I checked and Porthole is supposed to be working on IE8 but it is quite straightforward to check for yourself that it's not:

Go to http://sandbox.ternarylabs.com/porthole/ with IE, and set the compatibility mode to IE8 (window.postMessage shouldn't be defined, Porthole is switching to legacy mode) and the demo does not work!

Any idea why? Do you know any workaround?

Thanks,
Clément

Location of proxy.html

Should the file proxy.html be placed in the same folder as the content you want to load? Like in your examples? Nothing is said at the docs about it.
http://demo.auberger.com/porthole/
http://demo.auberger.com/porthole/proxy.html

Or could it be located anywhere else:
http://demo.auberger.com/controller/myAction
http://demo.auberger.com/controller/proxy

I'm using Laravel framework and I'm not quite sure how to deal with this...
I tried to follow your docs, but still having the message Refused to display...in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'

This is how I'm doing it:
Main page:

<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script type="text/javascript" src="http://sandbox.ternarylabs.com/porthole/js/porthole.min.js"></script>
    <script type="text/javascript">
        function onMessage(messageEvent) {}

        var windowProxy;
        window.onload = function() {
            // Create a proxy window to send to and receive 
            // messages from the iFrame
            windowProxy = new Porthole.WindowProxy(
                'http://192.168.xxx.xxx/monitor/proxy', 'guestFrame');

            // Register an event handler to receive messages;
            windowProxy.addEventListener(onMessage);
        };
    </script>
</head>

<body>

<iframe  src="http://192.168.xxx.xxx/monitor/myAction"  style="border: 0; width: 100%; height: 100%" scrolling="no" id="guestFrame"  name="guestFrame"></iframe>

</body>
</html>

In my iframe:

<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script type="text/javascript" src="http://sandbox.ternarylabs.com/porthole/js/porthole.min.js"></script>
    <script type="text/javascript">
        var windowProxy;
        window.onload = function() {
            // Create a proxy window to send to and receive 
            // messages from the parent
            windowProxy = new Porthole.WindowProxy(
                'http://10.72.xxx.xxx/laravel/public/monitor/proxy');

            // Register an event handler to receive messages;
            windowProxy.addEventListener(function(event) {
                // handle event
            });
        };
    </script>
</head>
<body>My content</body>

</html>

IE8 caused error: "Porthole: Could not find window proxy object on the target window" while FF works fine

Hi,
I know the demo is working fine on IE7/8, but I am completely unable to make it working with IE8 on my application.
It works fine on Chrome, FF and IE9, but not on IE8.

My parent and iframe uses SSL.

This is what I get on IE9 with IE8 compatibility mode:

LOG: Porthole: Using legacy browser support 
Porthole: Could not find window proxy object on the target window 

but it still works well on IE9 and other normal browsers with the same code.

Unfortunately I know JS just a bit, but I google and found an idea to wrap postMessage call in setTimeout:

var func = function () {
        windowProxy.postMessage('sid=B099000003&msisdn=48791464671');
};
window.setTimeout(func, 0);

But it doesn't help. Another strange this is that for pure IE8 I even don't get any LOG message from Porthole on console.

Do you have any idea what might cause the problem? Or anything I could do to help you find it?
Thanks.

IE7 wondowproxy.post does not trigger cross domain posting

I am currently implementing an single sign on solution with porthole.js. I undertand that IE7 does not have native support for JSON and hence have included the JSON2.js library with the project. This does not seem to work (there are no error mesages begin popped up)..although it does work in firefox 3.0.11. Through an advanced debugging technique (alerts) the windowproxy object seems to use the 'Legacy browser support' for posting. Do you have any thoughts?

Any solution for IE 6?

Hey there,

I created a simple test application using porthole. Unfortunately, the application seems to not work in IE 6 (I have to use this old browser version, because the application runs on a Windows CE 6 machine).

Is there any fix/workaround for this or do you know an alternative method to crossdomain JavaScript in IE 6?

Thanks.

Regards,
flogy

Call not working in firefox and IE

i have a site which open up a new iframe in facebox popup and have included the porthole js in both the webpages, in chrome i am able to pass close message but in firefox and IE it does not happens
in console it has only Porthole: Using built-in browser support this written,

No git tags on GitHub repository

Hey @georges,

I'd like to host your library, porthole on cdnjs — It is one of the most famous free and public web front-end CDN services which is used by ~1,143,000 websites worldwide.

The git auto-updater for cdnjs relies on git tags to recognize a release version and automatically update the library in the cdnjs repo.

If it's not too much to ask, can you please add git tags for this repo?

cdnjs/cdnjs/11143

module.exports

// porthole.js
window.exports.Porthole = Porthole;

//myiframe.js
var Porthole = require('../vendor/porthole/src/porthole');

// module exports exports:
Porthole.Porthole.WindowProxy()

Should it not be?

// porthole.js
window.exports = Porthole;

//myiframe.js
var Porthole = require('../vendor/porthole/src/porthole');

// module exports exports:
Porthole.WindowProxy()

Bower package name change?

Hey one of my projects I installed this module with just term porthole but now in bower its named ternarylabs.porthole. Is this correct? The bower json is suggesting this module is still called porthole.

Postmessage Error

porthole.js:314 Uncaught TypeError: this.getTargetWindow(...).postMessage is not a functionPorthole.WindowProxyHTML5.Porthole.WindowProxyBase.extend.dispatchMessage @ porthole.js:314Porthole.WindowProxyBase.PortholeClass.extend.post @ porthole.js:204window.onload @ (index):62

Porthole intefering with WebSocket

I'm using porthole to allow an iFrame to communicate with the parent page. The iFrame has a WebSocket connection to the server, and for some reason after I install the porthole it disconnects my WebSocket. I tried reconnecting it on disconnect, but it keeps getting disconnected every second or so. Any ideas what might be causing that?

windowProxy is undefined

I am trying to use the plugin created by you but running in to following issue
windowProxy is undefined

here is my use-case
i am submitting my from to server using HTTPS (my main page is in HTTP) and i am posting the server response on the Iframe (hidden)
based on the result provides by the server my intentions are to call a method on the parent and due to same origin policy i am not able to call it in normal condition.
i have the following setup in my system.On the parent window i have the following entry inside the head section

    var windowProxy1;
        window.onload=function(){ 
         // Create a proxy window to send to and receive 
         // messages from the iFrame
         windowProxy1 = new Porthole.WindowProxy(
        'https://localhost:9002/myApp/proxy.html', 'guestFrame');
         // Register an event handler to receive messages;
        windowProxy1.addEventListener(onMessage);
        };
    function onMessage(messageEvent) { 
        alert(messageEvent.status);
    }
</script>```

this is what i am sending from server to the Iframe

```<html>
 <head>
  <script type="text/javascript">
    var windowProxy;window.onload=function(){
      windowProxy = new Porthole.WindowProxy('http://localhost:9001/myApp/proxy.jsp');
        windowProxy.addEventListener(function(event){ });
        };
</script>
</head>
<body onload="windowProxy.post({'status':'error'},{'message':securityLoginStatus.getLoginFailedException()});\">
  <script type="text/javascript"> </script>
</body>
</html>```

but when server is sending back the response i am getting following issue that windowProxy is not defined.

I am not sure why this behavior is occurring.Can you please throw some light on this behaviour

Fork a New & Maintained Project

Somebody else needs to take control of this project and/or fork and actually maintain it. There are a ton of pull requests that are completely legitimate and very useful that have not been merged. It's very frustrating.

Is it necessary to create a proxy.html file at the iframe's domain?

Is it necessary to create a proxy.html file at the iframe's domain? It seems like it should be possible to have the iframe itself act as the proxy. I understand why a proxy.html is needed on the parent frame's domain (you can't post cross domain up to a parent frame, so you post to a child frame with the parent's domain that relays the message), but the parent can post cross domain into its child frames.

Post/Response

Great tool! I was wondering if there has ever been discussion about how to receive data back from a child frame immediately after a post from the parent frame. Example:

Parent Frame, in some type of mootools/jquery class-like object:

getDataForThing: function(thingId){
    var post = this.proxy.post({ // posts to a child frame
        cmd: 'getDataForThing',
        thingId: 1
    });
       console.log(post) // {data: 123}
}

Then, maybe in the child Frame logic:

proxy.addEventListener(function(event) {
    switch (event.data.cmd){
        case 'getDataForThing':
            var data = 123;
            return data;
            break;
    }
});

Admittedly, I know very little about the underlying tech that makes this possible, but there's always hope for something creative! Thanks!

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.