5

I want to get the URL from an iframe when the user redirects by clicking links in the iframe. The source of the iframe is not the same as the web application.

For example:

<iframe src="startingUrl" class="embed-responsive-item" id="iframe" sandbox="" allowfullscreen</iframe>

I add a load listener on the iframe to detect when the user redirects to other urls in this iframe:

const iframe = document.getElementById("iframe");

iframe.addEventListener("load", (evt) => {
    const location = iframe.contentWindow.location;

    console.log(location); // this gives me a Location object where I can see the href property
    console.log(location.href); // this gives me a SecurityError: Permission denied to get property "href" on cross-origin object, I also tried to get a copy of the object but that doesn't work either.
});

I know what causes this problem and I also know it is not possible. But I need to find a way to get the current URL of the page. If this is a no go then I want that the user who uses this web application can copy the url of the iframe and put it in an input field.

Now they can do "View frame source" in chrome and This frame: view frame source or info in Firefox. But this is too complicated for the user. Is there a way they can see the URL in the iFrame or a way for the user to get the URL simpler.

The site in the iFrame is not mine.

All help is much appreciated!

Laurent Dhont
  • 658
  • 4
  • 17

3 Answers3

1

Short answer: This is a no go, unless you have the support of the other site in your iframe and they are willing to add the code in @박상수 answer.

Longer answer: You could set up a proxy server to inject the required code to make this work, but then you will run into legal and ethical difficulties, so I am not going to explain how to do that in depth.

Another approach might be to create a browser extension and have your users install that. Again I should point out FaceBook has in the past ran into ethical difficulties taking this approach.

Ultimately their are very good security reasons why the browser stops you doing this and you should probably respect those reasons and not do it.

David Bradshaw
  • 10,116
  • 3
  • 33
  • 61
  • 1
    We are not as big as facebook, long off. I think this has been very helpfull. I will give you the reputation after I think about it ;-) – Laurent Dhont Nov 30 '19 at 12:01
0

If you don't see the code below, check the link below.

console.log(iframe.src);

Check out this link

SecurityError: Blocked a frame with origin from accessing a cross-origin frame

let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
window.addEventListener('message', event => {
    // IMPORTANT: check the origin of the data! 
    if (event.origin.startsWith('http://your-first-site.com')) { 
        // The data was sent from your site.
        // Data sent with postMessage is stored in event.data:
        console.log(event.data); 
    } else {
        // The data was NOT sent from your site! 
        // Be careful! Do not use it. This else branch is
        // here just for clarity, you usually shouldn't need it.
        return; 
    } 
}); 
박상수
  • 34
  • 1
0

You will want to override the error being automatically thrown:

const iframe = document.getElementById('iframe');
iframe.addEventListener('load', evt => {
  const loc = iframe.contentWindow.location;
  try{
    loc.href;
  }
  catch(e){
    if(e.name === 'SecurityError'){
      console.log(iframe.src);
    }
  }
});
<iframe src='https://example.com' class='embed-responsive-item' id='iframe' sandbox='' allowfullscreen></iframe>
StackSlave
  • 10,198
  • 2
  • 15
  • 30
  • I already tried this, but the source of the iframe doesn't change. I just get the original src, thanks! – Laurent Dhont Nov 26 '19 at 01:18
  • I don't understand what you mean. I assumed `startingUrl` was an absolute path, based on your poorly asked question. If it's a relative path, I assume you do have access, no? – StackSlave Nov 26 '19 at 01:53
  • No, I don't. I get these from a big database and load them with a view engine. How can I improve my question? – Laurent Dhont Nov 26 '19 at 02:27