experchange > javascript

Andrew Poulos (12-06-18, 06:57 AM)
I need a frameElement to send a self reference to the parent so I tried this

let obj = {};
obj.type = "ref";

if (window.frameElement !== null) {
obj.value = window.frameElement;
console.log(obj.value);
window.parent.postMessage( JSON.stringify(obj), "*");
}

and in the parent

window.addEventListener('message',function(evt) {
let rec = JSON.parse(evt.data);
if (rec.type == "ref") console.log(rec.value);
}, false);

While obj.value is a frameElement rec.value is only ever an empty object.

Can postMessage send a window reference? If so, how?

Andrew Poulos
Andrew Poulos (12-06-18, 10:02 AM)
On 6/12/2018 3:57 pm, Andrew Poulos wrote:
[..]
> }, false);
> While obj.value is a frameElement rec.value is only ever an empty object.
> Can postMessage send a window reference? If so, how?


Ok, I've just found the 'source' property
<https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>
which I think will do what I want.

Andrew Poulos
Evertjan. (12-06-18, 11:05 AM)
Andrew Poulos <ap_prog> wrote on 06 Dec 2018 in
comp.lang.javascript:

[..]
> While obj.value is a frameElement rec.value is only ever an empty
> object.
> Can postMessage send a window reference? If so, how?


you can send the window itself,
and extract e.srcElement in the parent,
for whatever reason,
no need for 'ref' or jason:

======= test.html =======
<iframe src='iframe.html'>
</iframe>

<script>
window.addEventListener(
"message",
e => console.log(e.srcElement, e.data),
false);
</script>
=========================

======= iframe.html =====
<script>
window.parent.postMessage('hi', "*");
</script>
=========================
Andrew Poulos (12-09-18, 10:44 AM)
On 6/12/2018 8:05 pm, Evertjan. wrote:
[..]
> window.parent.postMessage('hi', "*");
> </script>
> =========================


I'm still having trouble with it. Within the parent e.srcElement appears
to only refer to the parent itself and not to the iframe:

window.addEventListener(
"message",
e => console.log(e.srcElement == window.top), // returns true
false);

The parent and the iframe contents are not on the same domain and
anything I've tried either fails because of cross domain security or
returns a reference window.parent

It looks like I need to use the parent to find the iframe and not (what
I wanted to happen) have the iframe "announce" itself to the parent.

Andrew Poulos
JJ (12-09-18, 11:22 AM)
On Sun, 9 Dec 2018 19:44:43 +1100, Andrew Poulos wrote:
> I'm still having trouble with it. Within the parent e.srcElement appears
> to only refer to the parent itself and not to the iframe:
> window.addEventListener(
> "message",
> e => console.log(e.srcElement == window.top), // returns true
> false);


Try checking the element's `frameElement` property.
Julio Di Egidio (12-09-18, 11:46 AM)
On Thursday, 6 December 2018 05:57:14 UTC+1, Andrew Poulos wrote:

[..]
> }, false);
> While obj.value is a frameElement rec.value is only ever an empty object.
> Can postMessage send a window reference? If so, how?


Read the docs:

<https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>

window.postMessage is about intercommunication between any two *windows*: it
does not really care about frames vs popups vs other.

The first parameter to postMessage is serialised for you already.

OTOH, you cannot (usually) serialise/deserialise complex runtime objects such
as window or document, so do not even try: rather use the postMessage facility
as a messaging system only, to send "data/commands" across (use postMessage
to reply back as well if you need: i.e., again, use it as a messaging system
where each party can potentially send *messages* to the other instead of
directly accessing each other's properties or methods).

That said, check the properties of the *event* object you get in onmessage,
i.e. on the receiving end: in particular, there is a 'source' property which
is a reference to the sender window... But, again, I use it only to post a
message back if I need.

Beware also of other CORS issues: e.g. if it's a frame within a parent, set
the Content-Security-Policy frame-src (or equivalent) on the parent...

Julio
Julio Di Egidio (12-09-18, 12:06 PM)
On Sunday, 9 December 2018 10:46:52 UTC+1, Julio Di Egidio wrote:
[..]
> message back if I need.
> Beware also of other CORS issues: e.g. if it's a frame within a parent, set
> the Content-Security-Policy frame-src (or equivalent) on the parent...


Sorry, let me clarify on that out-of-the-blue last paragraph:

Actually, to validate origins, as also shown in the examples in the docs, you
should check the event.origin property against some list of allowed URLs.

But, if all you have is a main window communicating with an iframe, the CSP
frame-src setting in the parent page is enough to filter out unwanted content
in the iframe, then you can skip programmatic checks of the event-origin *in
the parent*: you'd still need to check origins in the framed page...

Julio
Julio Di Egidio (12-09-18, 12:51 PM)
On Sunday, 9 December 2018 11:06:27 UTC+1, Julio Di Egidio wrote:
> On Sunday, 9 December 2018 10:46:52 UTC+1, Julio Di Egidio wrote: <snip>
> Sorry, let me clarify on that out-of-the-blue last paragraph:
> Actually, to validate origins, as also shown in the examples in the docs, you
> should check the event.origin property against some list of allowed URLs.
> But, if all you have is a main window communicating with an iframe, the CSP
> frame-src setting in the parent page is enough to filter out unwanted content
> in the iframe, then you can skip programmatic checks of the event-origin *in
> the parent*: you'd still need to check origins in the framed page...


Nah, just drop the last part: the main page itself could be framed by a
malicious site, and this could be posting messages, so always check origins!

I did build an app where I do what I said above: but it was a hybrid mobile
app, not a public facing web site. Anyway, now that I think of it, I am not
anymore sure that it was not a security hole...

Just sorry for the confusion.

Julio
Andrew Poulos (12-10-18, 01:11 AM)
On 9/12/2018 9:51 pm, Julio Di Egidio wrote:
> On Sunday, 9 December 2018 11:06:27 UTC+1, Julio Di Egidio wrote:
> <snip>
> Nah, just drop the last part: the main page itself could be framed by a
> malicious site, and this could be posting messages, so always check origins!
> I did build an app where I do what I said above: but it was a hybrid mobile
> app, not a public facing web site. Anyway, now that I think of it, I am not
> anymore sure that it was not a security hole...
> Just sorry for the confusion.


Thanks but I'm still suffering with this.

<https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>
says that I can use HTMLIFrameElement.contentWindow (to reference an
embedded <iframe> from its parent window) but when I try this

window.parent.frames['frm'].contentWindow.postMessage(JSON.stringify(obj),
'*');

I get "Blocked a frame with origin "http://www.example.com" from
accessing a cross-origin frame."

Does that mean I can't call an iframe from another iframe?

Andrew Poulos
Andrew Poulos (12-10-18, 01:23 AM)
On 10/12/2018 10:11 am, Andrew Poulos wrote:
> On 9/12/2018 9:51 pm, Julio Di Egidio wrote:
> Thanks but I'm still suffering with this.
> <https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>
> says that I can use HTMLIFrameElement.contentWindow (to reference an
> embedded <iframe> from its parent window) but when I try this
> window.parent.frames['frm'].contentWindow.postMessage(JSON.stringify(obj),
> '*');
> I get "Blocked a frame with origin "http://www.example.com" from
> accessing a cross-origin frame."


I tried

window.parent.document.getElementById("frm").conte ntWindow.postMessage(JSON.stringify(obj),
'*');

and it seems to work ie. it doesn't throw an error. And I thought that
document.getElementById("frm") and window.frames("frm") were identical -
when referencing the same iframe :-(

Andrew Poulos
Julio Di Egidio (12-10-18, 02:10 AM)
On Monday, 10 December 2018 00:23:43 UTC+1, Andrew Poulos wrote:

> I tried
> window.parent.document.getElementById("frm").
> contentWindow.postMessage(JSON.stringify(obj), '*');


Again, you don't need to serialise/deserialise the message:

<https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>

> and it seems to work ie. it doesn't throw an error. And I thought that
> document.getElementById("frm") and window.frames["frm"] were identical -
> when referencing the same iframe :-( [I have fixed the parentheses.]


You just cannot index window.frames by frame name:

<https://developer.mozilla.org/en-US/docs/Web/API/Window/frames>

Indexing by frame name existed in IE once upon a time...

Julio
Andrew Poulos (12-10-18, 03:44 AM)
On 10/12/2018 11:10 am, Julio Di Egidio wrote:
> On Monday, 10 December 2018 00:23:43 UTC+1, Andrew Poulos wrote:
>> I tried
>> window.parent.document.getElementById("frm").
>> contentWindow.postMessage(JSON.stringify(obj), '*');

> Again, you don't need to serialise/deserialise the message:
> <https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>


Ah, thanks. How do I deserialise the received message?

>> and it seems to work ie. it doesn't throw an error. And I thought that
>> document.getElementById("frm") and window.frames["frm"] were identical -
>> when referencing the same iframe :-( [I have fixed the parentheses.]

> You just cannot index window.frames by frame name:
> <https://developer.mozilla.org/en-US/docs/Web/API/Window/frames>
> Indexing by frame name existed in IE once upon a time...


Dang, that's what I get for not checking everything.

Andrew Poulos
Thomas 'PointedEars' Lahn (12-10-18, 05:17 AM)
Andrew Poulos wrote:

> On 10/12/2018 11:10 am, Julio Di Egidio wrote:
> Ah, thanks. How do I deserialise the received message?


You are not paying attention. I have marked the important part for you.

>>> and it seems to work ie. it doesn't throw an error. And I thought that
>>> document.getElementById("frm") and window.frames["frm"] were identical -
>>> when referencing the same iframe :-( [I have fixed the parentheses.]

>> You just cannot index window.frames by frame name:


Sure you can. My category filter in
<http://PointedEars.de/ufpdb/main.en> that does just this –

function callDBfilter(filterID)
{
parent.frames['ufpdb_index'].setDBfilter(filterID);
return false;
}

– still works in all frame-DOM-supporting user agents.
May it have a Happy 14th Birthday!

>> <https://developer.mozilla.org/en-US/docs/Web/API/Window/frames>
>> Indexing by frame name existed in IE once upon a time...


Utter nonsense. The MDN article is hopelessly incomplete and the
wannabe–troll has *still* no clue what he is talking about.

There is just a difference between a frame *name* and a frame *ID*.
Andrew Poulos (12-10-18, 06:25 AM)
On 10/12/2018 2:17 pm, Thomas 'PointedEars' Lahn wrote:
> Andrew Poulos wrote:
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> You are not paying attention. I have marked the important part for you.


Right, I've got it now.

[..]
> Utter nonsense. The MDN article is hopelessly incomplete and the
> wannabe–troll has *still* no clue what he is talking about.
> There is just a difference between a frame *name* and a frame *ID*.


I set the frame name that matched the frame ID yet, for me, using
window.frames('frm').contentWindow.postM... failed while
document.getElementById('frm').contentWindow.postM ... didn't.

Andrew Poulos
Thomas 'PointedEars' Lahn (12-10-18, 10:28 PM)
Andrew Poulos wrote:
> On 10/12/2018 2:17 pm, Thomas 'PointedEars' Lahn wrote:
> I set the frame name that matched the frame ID yet, for me, using
> window.frames('frm').contentWindow.postM... failed while
> document.getElementById('frm').contentWindow.postM ... didn't.


Because “window.frames” is NOT (a reference to) a *method*.

RTFConsole, RTFM!

Similar Threads