0

So I have read through the other posts here on cross origin requests and I don't think anything is relevant to what I'm trying to do. Forgive me if there is a duplicate post out there somewhere!

In a nutshell, I have created a bookmarklet, which is essentially an iframe that executes a script which (is supposed to) grabs the url of the current window and makes a post request with that url (and user token) to my backend api. More or less what the Instapaper bookmarklet does.

So, my web app is a React app with a component that is an <a> with a href that contains a script that appends an iframe to the current page. The src of that appended iframe is a html file in my app's public folder. That html file has a script which is supposed to do what I've described in the paragraph above. I drag the bookmarklet from my web app to the bookmarks bar, and from another page on the web, click it, hoping it saves that url to my api. Instead I get bookmarklet.js:4 Uncaught DOMException: Blocked a frame with origin "https://my-app.com" from accessing a cross-origin frame..

The bookmarklet (the component rendered on the page) is (code is minified):

<a href='javascript:!function(){var t=document.createElement("iframe");t.src="https://my-app.com/bookmarklet.html",window.parent.document.body.appendChild(t)}();' className="btn btn-default">Save</a>

The bookmarklet.html file has this script tag: <script src="https://my-app.com/bookmarklet.js"></script>

The script in bookmarklet.js is:

(function() {
  const token = localStorage.getItem("token");
  const url = window.parent.document.location.href
  axios.post('https://my-api.com/api/v1/links/bookmarklet', {
    user: { token },
    link: { url }
  })
  .then(alert('Link posted'))
  .catch(err => {
      console.log(err)
    })
})();

Is there any way around this cross-origin limitation? I can see from other questions on this topic that there is mention of window.postMessage but I gather that's only if I own both domains? Many thanks in advance.

Ian Lenehan
  • 153
  • 10
  • If you can't control the domains, you've no way to access that other domain with a browser. There are good reasons for [same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy), you don't need a work-around. – Teemu Jul 26 '17 at 12:11
  • They OP effectively does control both domains. On one they have a bookmarklet (which provides full XSS access), on the other they have control of the site because it is there server. – Quentin Jul 26 '17 at 12:13
  • "I can see from other questions on this topic that there is mention of window.postMessage but I gather that's only if I own both domains?" — You have control. Your bookmarklet can inject JS into the domain you "don't" control. – Quentin Jul 26 '17 at 12:13
  • Thanks Quentin - I did read that other post but I guess I didn't fully understand it. I will see if I can work out how to use postMessage to achieve what I am after. I can't now but will post here with my results when done. – Ian Lenehan Jul 26 '17 at 12:22
  • So I'm really struggling to work out where I should be using the postMessage API. Is it when I'm collecting the url from the parent window (`window.parent.document.location.href`) or is it when making the post request to my backend api? Would you be able to make a suggestion as to how it might work with my particular issue? I'd be really grateful! – Ian Lenehan Jul 28 '17 at 10:32

0 Answers0