Search code examples
javascriptjqueryiframegreasemonkeytampermonkey

Not changing origin when passing data to iframe via message


Let's say I have 2 pages: foo.com and bar.com I have a script running on each of them using Tapermonkey. I want to script on foo.com pass data to the script on bar.com. Because foo and bar are on different domains I can't pass data directly (GM_setValue, localStorage, webSQL).

But I've found this tutorial: https://jcubic.wordpress.com/2014/06/20/cross-domain-localstorage/

The trick is to attach iframe with bar.com to foo.com, send data via postMessage and in iframe receive data and save it to the localstorage. Then the second script on foo.com will be able to read data from localstorage.

Here's the first script:

var name = "John";
var div = document.createElement('div');
div.id = "result";
document.body.appendChild(div);   
var barPage = 'http://bar.com/';
document.getElementById("result").innerHTML = "<iframe src='"+ barPage +"' width='100%' height='100px' id='bariframe' />";

$(document).ready(function() {
    var win = div.children[0].contentWindow;

    var script = "window.addEventListener('message',function(e){if(e.origin!=='http://bar.com/'){console.log('wrong origin: '+e.origin);return}alert(e.data);var payload=JSON.parse(e.data);localStorage.setItem(payload.key,JSON.stringify(payload.data))});";

    var scriptObj = win.document.createElement("script");
    scriptObj.type = "text/javascript";
    scriptObj.id = "barscript";
    scriptObj.innerHTML = script;
    win.document.body.appendChild(scriptObj);        

    var obj = {
        "name": name
    };
    var json = JSON.stringify({key: 'storage', data: obj});
    win.postMessage(json, "*");
    console.log("Sent: " + json);
});

What script does:

1) create empty div and add it on the bottom of foo.com

2) after document had loaded I inject javascript into iframe and send data to it via postMessage

3) injected script should receive data and save it to localStorage.

But the problem is I'm still getting foo.com origin inside that script. And it should be bar.com, shouldn't it?

Because of that when I'd really open foo.com script here won't have this data.

Why doesn't it work?


Solution

  • You can't access inside the cross origin iframe you are creating to append anything to it this way due to "same origin policy".

    You need an html page from bar.com that has the postMessage listener in it to make your approach work