3

When using an iframe, how can I get the value of an attribute from the iframe within the iframe?

Here is my code:

<iframe src="slideriframe.html" name="iframe_a" customAttr="example" style="border:none"></iframe>

Here is what I have currently:

alert(window.frameElement.getAttribute('customAttr'));

Here is the error:

Uncaught SecurityError: Failed to read the 'frame' property from 'Window': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.

Thanks

Simon
  • 7,991
  • 21
  • 83
  • 163
  • You cant, if the iframe is from another domain. for other solutions read the other answers provided on SO, e.g. http://stackoverflow.com/questions/217776/how-to-apply-css-to-iframe – cari Jun 22 '15 at 02:44
  • 1
    The reason you see this error is because of the [Same Origin Policy](https://en.wikipedia.org/wiki/Same-origin_policy). In extremely simple words, this means you're not allowed to access code that doesn't belong to you. There are several ways to relax this policy, but you can read more about that on the Wiki page I've linked. – icecub Jun 22 '15 at 03:27

1 Answers1

2

You need to use the postMessage API which provides a simple method for comunicating between an iFrame and it's parent. You would send a message to the parent, which would then look up the value and post another message back to the iFrame.

To send a message to the parent page you call it as follows.

parent.postMessage('Hello parent','http://origin-domain.com');

In the other direction we can send the message to the iFrame with the following code.

var iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage('Hello my child', 'http://remote-domain.com:8080');

To recevie a message create an event listerner for the message event.

function receiveMessage(event)
{
  if (event.origin !== "http://remote-domain.com:8080")
    return;

  console.log(event.data);
}

if ('addEventListener' in window){
    window.addEventListener('message', receiveMessage, false);
} else if ('attachEvent' in window){ //IE
    window.attachEvent('onmessage', receiveMessage);

These examples uses the origin property to limit where the message is sent to and to check where it came from. It is possible to specify * to allow sending to any domain and you may in some cases you may want to accept messages from any domain. However, if you do this you need to consider the security implications and implement your own checks on the incoming message to ensure it contains what your expecting. In this case the iframe can post it's height to '*', as we might have more than one parent domain. However, it's a good idea to check incoming messages are from the iFrame.

function isMessageFromIFrame(event,iframe){
    var
        origin  = event.origin,
        src     = iframe.src;

    if ((''+origin !== 'null') && (origin !== src.substr(0,origin.length))) {
        throw new Error(
            'Unexpect message received from: ' + origin +
            ' for ' + iframe.id + '. Message was: ' + event.data  
        );
    }

    return true;
}
David Bradshaw
  • 11,859
  • 3
  • 41
  • 70