0
votes

Chrome v75 appears to have introduced a bug whereby if you replace an iFrame's src programatically, it will replace the entire page instead of the iFrame.

This didn't happen on v74 and I can't get a test case to work (yet), it just fails in our site. (The site hasn't changed since going from v74 to v75, only Chrome has changed)

It appears to work fine the first time but then when you change it again (in our case viewing report drill downs) it causes the entire page (i.e. the iFrame's Parent) to load the src you were trying to load into the iFrame.

It also doesn't matter if you use pure Javascript or (in our case) JQuery, both cause the same issue.

EDIT: After a few hours detective work, I've found the bug. Setting the tag in the iFrame's content causes Chrome to load the iFrame's content into it's parent rather than the iFrame itself.

I've setup a Plunker account with a demo: https://plnkr.co/edit/UQ0gBY?plnkr=legacy&p=info

Just so I can post the link to Plunker, here is the code for the main file & the iframe content

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<script>

    function onLoaded() {
        // find element
        let button = document.getElementById("button");
        button.addEventListener("click",function(e){
            // Add a random number on the end as a cache buster
            document.getElementById('frame-finance-custom').src = 'test2.html?rnd=' + Math.random();
        },false);
    };

    document.addEventListener('DOMContentLoaded', onLoaded, false);

</script>
</head>
<body>
<div>IFrame Src Changing Test</div>
<div>
    <div id="div-frame-finance-custom" style="float:left;width:33%">
        <iframe id="frame-finance-custom" name="frame-finance-custom" class="iframe"
                style="border:1px solid black; width: 100%; height: 350px; overflow-y: scroll; vertical-align: top;">
            no data
        </iframe>
    </div>
    <div style="float:left;margin-left:1em;">
        Detail: Loading an iframe page with a &lt;Base&gt; tag in it with target set to "_parent" will cause any refresh of that frame to replace the parent document<BR>
        <BR>Instruction: <UL><LI>Click the 'Update Frame' Button, this will load test2.html into the frame. <LI>Click it again & it will replace the iframe's parent with the content of the iFrame.</UL>
        <BR>Confirmation: Remove the &lt;Base&gt; tag from the header of test2.html & reload, it will work as expected.
    </div>
</div>
<br clear=both>
<div>
    <button id="button">
        Update Frame
    </button>

</div>
</body>
</html>

IFrame Content (test2.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <base target="_parent"/>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>This is the frame content</div>
</body>
</html>

Note, using their new layout it doesn't work, but using their legacy layout it does. Feel free to save the files locally and use chrome directly too.

1
You need to show code mate, we cant work on theoretical questions. - Rafael Herscovici
@Dementic - as I said, I can't get a simple test case to reproduce it and as I also said, the code isn't the issue - it worked fine in v74. Something has changed in Chrome in v75 which has caused this effect. I am working on a test case, but I'm also working on a fix first so users can actually use the system! - Steve Childs
@SteveChilds — "I can't get a simple test case to reproduce it" — That's a prerequisite for a debugging question here. - Quentin
@Quentin - I appreciate that I was hoping to catch anyone else googling for a fix to the same issue with the hope that together we may be able to put the collective heads together and work out a fix. Its a bit hard when you hit a bug in new Chrome release itself that appeared a few days ago! As I said, the code isn't the issue - it can't be when the same code works fine in v74, but fails in v75 - Steve Childs
@Dementic - Demo code now added, now I found out what the bug was. - Steve Childs

1 Answers

0
votes

Ok, so this turned out to be a bug in Chrome rather than anything else, so yes, strictly not a SO question, but seeing as SO ranks so well in Google (other search engines are available), I thought it better to leave it here as a solution rather than simply delete it, just incase anyone else has a similar problem.

The reason is outlined as an edit in my question, the solution is to remove the <base target="_parent"> tag from the iFrame and programatically add the 'target="_parent"' attribute to any links in the iFrame.

We do this via jQuery, I'm sure its just as easy via vanilla Javascript.

$('a').attr('target','_parent');

Add that to the javascript that runs when a page has loaded and it'll replace add target="_parent" to any links on the page.

e.g.

<script>
  function onLoaded() {
     // find all links and add the target attribute
     $('a').attr('target','_parent');
  };

  document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>

As @Kaiido says in his comment, its apparently fixed in Chrome v77, but this isn't the current (as of June 2019) stable release, so we've had to add the workaround into production so that our CRM works with Chrome v75. Thanks to @Kaiido for confirming that.