2

My application uses iframes to display content. I need to detect whether a page is loaded in an iframe. The problem is I need to do it with php, javascript manipulation of the DOM is not enough, I need to do something with php before page is loaded. I inject get parameters like inframe=1 on every anchor click inside the iframe, it works. But I can't find a good workaround for post requests. I tried with hidden input fields, but it doesn't work in my case, I don't have any control over it, since this application is a plugin for another.

The only workaround I have for post requests, is to check on iframe load, whether new location parameter contains 'inframe', if it doesn't then I add 'inframe' to the location and load the link again. It works, but page loads twice after form submits. I could hide the iframe on submit and show it after page is loaded second time, so it looks like it loaded once, but still loading it 2 times is noticeably slower and unacceptable as a solution.

So this is my not so good solution:

this.iframeReload = function($iframe) { //event listener for iframe load

var newSrc=$iframe.get(0).contentWindow.location.href;

if (newSrc.indexOf('inframe')==-1) {
    console.log('redirecting');
    if(newSrc.indexOf('?')==-1) href+='?inframe=1';
    else newSrc+='&inframe=1';
    $iframe.get(0).contentWindow.location=newSrc;
    return 0; //terminate function and reload the iframe with parameter
}
$iframe.ready(function() { /*stuff to do after iframe loads*/ });

}

Is there a better way to do it? Like intercept the contentWindow.location change and add the parameter to it before even the page loads. I searched in Google and I only found to use load event, which I already use and it doesn't help much. Or maybe there is completely different solution? Any ideas appreciated. I spent almost 4 hours on things related to this problem.

Now after I've written it, mutation observer has come to my mind. I don't know much about it. Can it track contentWindow.location changes? I'm gonna try it.

Maciej Krawczyk
  • 10,012
  • 5
  • 30
  • 38
  • Do you have control over the form that `POST`'s? If yes, you could always add the `?iniframe=1` to the action. – Kevin Nagurski May 22 '15 at 10:34
  • I tried to do it. Unfortunately it's the same case as hidden inputs. It has no effect. The action of the request is not the file from where it's called. So it's like the form is on form.php and the action is on action.php. Post request to action.php, action.php redirects to form.php with $_POST empty. I can do nothing about it. I can't touch post.php and action.php. – Maciej Krawczyk May 22 '15 at 10:45
  • Not sure I entirely follow you. If `form.php` loads and is determined to be in an iFrame, sets it's location to `form.php?iniframe=1` and submits to `action.php?iniframe=1`, which then redirects back to `form.php?iniframe=1`. You can always could on the `$_GET` regardless of whether it was a `POST` form submission. – Kevin Nagurski May 22 '15 at 10:48
  • BTW, have a look into setting the location with [`pushState`](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#The_pushState()_method) instead of a refresh. – Kevin Nagurski May 22 '15 at 10:50
  • which then redirects back to form.php. It's WordPress actually, but I really searched a lot on how could I pass the get parameter through post requests, but I found nothing. – Maciej Krawczyk May 22 '15 at 11:40
  • As Kevin said, I'm not sure that I entirely follow you. The goal is to reduce wait time. And that delay is from the iframe loading a second time on post? So it's a resource heavy page? Would setting the form target to a lighter page help? See: [How do you post to an iframe?](http://stackoverflow.com/questions/168455/how-do-you-post-to-an-iframe) Seems like an interesting problem, but we probably need more information to come up with a solution. – Roberto May 22 '15 at 12:02
  • The goal is to inject &inframe=1 to any link that doesn't have this parameter and do it without loading it twice. So for example the page in the iframe wants to load form.php, javascript outside the iframe notices it, adds ?inframe=1 to the link and then allows to load the link. But something like that is probably impossible, isn't it? – Maciej Krawczyk May 22 '15 at 12:36
  • I think I solved the problem. Not with javascript though. Sessions seemed the only solution. Actually it is session + anchor injecting +
    – Maciej Krawczyk May 22 '15 at 14:54

1 Answers1

0

There are a few options. From the PHP side you could look at the referrer $_SERVER['HTTP_REFERER'] to see if it's from a known list of iframe loading pages. HTTP_REFERER can be hit and miss so use it, but don't rely on it.

Second option would be to detect whether it's in an iFrame how you are doing and use pushState to add the ?iniframe=1. After that you can detect that and change the form's action to match action="action.php?iniframe=1". You'll still be able to pick this up on the PHP side (if (isset($_GET['iniframe'])) {) even though the form sent a POST.

When you do a redirect in the PHP side, just make sure that the ?iniframe=1 comes along for the ride too.

Kevin Nagurski
  • 1,869
  • 9
  • 23
  • refferer won't help at all. I tried it a month ago or so. What do you mean about pushState? How could it help? If I just change the url without reload, the get parameter will do nothing. – Maciej Krawczyk May 22 '15 at 11:41
  • I suppose it just has to do with what you're doing with the `?iniframe=1`. If it requires actual different PHP code, then yes, do the round trip to the server, if not, the the `history.pushState()` method will let you change the URL without reloading the page. – Kevin Nagurski May 22 '15 at 11:45