How do I identify if a link was opened by an iframe in a new tab?

Asked

Viewed 1,087 times

16

How to identify if any link originated from a iframe that I do not have access was opened in a new guide?

I tried with document.getElementById("i").addEventListener("click", a);, but from what I understand it is not possible to use onclick in a iframe unless it has direct access to the source code of the iframe

I tried with a div override but undo the first click on iframe it takes more than one click to open the link

So I looked for how to identify if a link was opened in a new tab and found nothing like it.

The user of my page has to complete a task on iframe when finishing the task within the iframe a page will open in a new tab, how to identify if the tab has been opened?

Example snippet:

document.getElementById("i").onclick = function a(){
console.log("ok")
}
Preencha com seu nome e conclua<br>
<iframe id="i" src="https://editor.sollic.com/iframe.html"></iframe>


The closest I came was through a div superimposing the iframe.

Sample page: https://editor.sollic.com/stackoverflow

Explaining the code: When passing the mouse over the div it will disappear by 1 second whenever the mouse is on it allowing you to click anywhere until the page goes out of focus, with this if the div is hidden and the out-of-focus page will activate the "trigger" who will send "ok" on console or in case of example link will change the background color to red.

But there are times it works correctly and in others it doesn’t work or it works wrong, like clicking anywhere and receiving the console message or changing the background color.
Snippet does not work properly because stackoverflow blocks.

var foco = true;

function con() { //função que será ativada ao passar o mouse
   window.onblur = function(){foco = false} //verifica se a pagina está fora de foco
   window.onfocus = function(){foco = true} //verifica se a pagina está em foco
   
   if(foco!=false) {document.getElementById("a").style.display='block'} //se a pagina estiver em foco reativa a div
   else {console.log("ok")} //se a pagina estiver em foco envia "ok" no console
}

function la() {document.getElementById("a").style.display='none'} //desativa a div
#a{
position:absolute;
z-index:1;
background:#000;
width:304px;
height:155px
}
<div id="a" onmouseover="setTimeout(con, 1000);la();"></div>
<iframe id="i" src="https://editor.sollic.com/iframe.html"></iframe>

  • Just a curiosity: what action you wanted to take when you detected that the new tab was opened?

  • At the moment the page will be redirected to the previous page

  • He’s young, not to be disheartening, but I don’t think that’s possible. An iframe is like a separate document inside another. The parent document does not hear events in the child document, unless it was of the same domain. When iframe opens a new tab, this event goes over the parent document, and does not create any kind of relationship between the parent document and the iframe document. The only event I can see that creates a certain connection between the two documents is the window.onblur, since, when a new one is opened, the blur is fired in the document of the tab that was active.

  • But the blur tb is fired when you change tab, there is no way to know if the event was triggered because of iframe.

  • I imagined that Blur would look like this, but if I have the address of the page that will open, it is possible to access the browser history if the page was opened?

  • There is no way to access the history via JS, even for security and privacy reasons. Ever thought a page to know which sites you have been visiting?

  • @Sam I did otherwise as described in the question, but it does not always work and I could not find what causes this problem, would be the browser cache or something like?

  • For me you should give this up. There is no way to function, for the reasons I described above. You will never know when a new tab has been opened by iframe.

  • All the answers are good, but they are nothing more than what I commented above =]

  • @Sam really are, but I offered the reward for viable ways to do that, like my code in question.

Show 5 more comments

2 answers

7


When it comes to iFrames, should be considered a decisive factor for the progress of your problem. The Policy of the same origin(SOP). [1] [2]

A web browser allows scripts contained in a first page access data on a second web page, but only if both web pages have the same origin. [1]


But how to know if I’m using an iframe of same origin that my website?
In comparison, two Urls have same origin if the protocol(http,https), door(if it is wishful) and host(if they are equal in both).

We will simulate that your site has the following URL:

http://meusite.markvaaz.com/pasta/index.html:

|URL                                        | RESULTADO     | RAZÃO 
+-------------------------------------------+---------------+------------------------------+ 
|http://markvaaz.com/pasta/site.html        |  Mesma Origem | Apenas caminhos diferentes.  |
|http://markvaaz.com/pasta/pasta2/site2.html|  Mesma Origem | Apenas caminhos diferentes.  |
|https://markvaaz.com/pasta/html.html       |     Falha     | Protocolo diferente(https).  |
|http://markvaaz.com:81/pasta/outro.html    |     Falha     | Portas diferente da padrão.  |
|https://editor.sollic.com/iframe.html      |     Falha     | Protocolo/host diferentes .  |

Note¹: The protocol http:// uses port 80 as standard.
Note²: To the IE port difference is not validated, so it would be considered Same Origin in IE if the URL accessed used another port.

If the result is Same Origin, you can use window.postMessage() to exchange information between your Objects, follow an example.

On its home page:

window.onload = function(){
   var frame = document.getElementById('i'); 
   frame.contentWindow.postMessage('Olá Frame.', '*'); 
};

In your iframe:

    window.addEventListener('mensagem', function(e)){
    console.log('mensagem recebida!');
};


It is possible to disable the Politics of the same origin of your browser?
There is a way to perform the manipulation between frames, however, it would become useless (even though it is valid to explain about it) for your case, since third parties will use your Website. Disable the policy of the same origin consists of a sequence of steps (can be from simple to complicated depending on which browser you want to disable SOP) that will affect only your browser and prevent the same scenario from occurring when climbing your server. Although it is not indicated to use the disablement, I recommend doing this only for testing and development cases, as it will leave your browser vulnerable to any access from unknown sources.

Sources:stackoverflow, stackoverflow, w3c, Developer., youtube.

7

That can’t be done in most cases.

This impossibility is a security measure adopted primarily to prevent threats such as XSS. However, if the iframe has the same origin of your site, you can access its content and make the modifications.

In the example below, the iframe could not be modified by Javascript, since the origins are different:

<!-- Assuma que a URL do site é google.com: -->

<!-- O `iframe` a seguir NÃO poderia ser "acessado", já que a origem "apple.com" é diferente de "google.com": -->
<iframe src="https://apple.com"></iframe>

In the following example, however, the iframe could be modified, since the origins are equal:

<!-- Assuma que a URL do site é google.com: -->

<!-- O `iframe` a seguir poderia ser "acessado", já que as origens são iguais: -->
<iframe src="https://www.google.com/search?q=StackOverflow"></iframe>

To access, you can do so:

//
// NOTA:
//
// Esse código só irá funcionar se você estiver em uma página
// cuja URL comece com "https://google.com"!
//

// Inserir um <iframe> na página:
document.body.innerHTML = '<iframe src="https://www.google.com/search?q=StackOverflow" style="width: 80vw; height: 60vh;"></iframe>'

// Capturar o elemento <iframe>:
const iframe = document.querySelector('iframe')

// Aguardar o conteúdo carregar:
iframe.addEventListener('load', () => {
  // Acessar o documento do <iframe>:
  const iframeDocument = iframe.contentDocument
    ? iframe.contentDocument
    : iframe.contentWindow.document

  // Colorir todos os links de vermelho para demonstração:
  iframeDocument.querySelectorAll('a').forEach((a) => {
    a.style.setProperty('color', 'red')
  })
})

In the above example (which to work must be executed on some page whose origin is google.com), all links from iframe shall be painted red.


In short, unless the origins are the same, you will not be able to identify whether the link has been opened or not, assuming it is contained in a iframe.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.