Search code examples
javascriptiframeinternet-explorer-11microsoft-edge

Patching document.write on Edge and IE


Here is a simple monkey patch for document.write which works in all major browsers but MS Edge and IE.

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <iframe id="first" width="300" height="250"></iframe>
        <script>
            var ifr = document.getElementById('first');
            var doc = ifr.contentWindow.document;

            console.log('Before patching:', doc.write);

            (function(doc) {
                var originalWrite = doc.write;
                doc.write = function() {
                    console.log('Patched');
                    return originalWrite.apply(doc, arguments);
                };
            })(doc);

            console.log('After patching:', doc.write);

            doc.write('<iframe id="second" width="300" height="250"></iframe>');

            console.log('After writing:', doc.write);
        </script>
    </body>
</html>

Expected behavior: doc.write after writing should be the same as after patching

Actual behavior: doc.write is undefined

Doesn’t work: Edge 18, IE 11

Works: Chrome, Firefox, Opera, Safari

Snippet to reproduce: https://jsbin.com/qutaxixeku/edit?html,console

Any ideas for workaround?

Update 2019-11-19:

Following Yu Zhou's answer. If I remove the patching logic altogether and log doc after writing, Microsoft Edge will show <Permission denied> error in HTMLDocumentPrototype as well. But if I log doc.write right after it, Microsoft Edge will show function write() { [native code] }

Permission denied

Moreover if I attempt to write to the iframe several times without patching, it will work fine on Edge:

doc.write('<div>One</div>');
doc.write('<div>Two</div>');
doc.write('<div>Three</div>');

Multiple writes

Snippet


Solution

  • It should be a by-design issue of Edge and IE11. It's not suggested to call document.write more than once in an iframe in Edge, even though it works with the native document.write method. Return to your issue, if you write to the iframe several times after your patching, Edge only shows one object:

    <!DOCTYPE html>
    <html>
        <head>
        </head>
        <body>
            <iframe id="first" width="300" height="250"></iframe>
            <script>
                var ifr = document.getElementById('first');
                var doc = ifr.contentWindow.document;
    
                console.log('Before patching:', doc.write);
    			
                (function(doc) {
                    var originalWrite = doc.write;
                    doc.write = function() {
                        console.log('Patched');
                        return originalWrite.apply(doc, arguments);
                    };
                })(doc); 
    
                console.log('After patching:', doc.write);
    
                //doc.write('<iframe id="second" width="300" height="250"></iframe>');
    			doc.write('<div>One</div>');
    			doc.write('<div>Two</div>');
    			doc.write('<div>Three</div>');
    
                console.log('After writing:', doc.write);
            </script>
        </body>
    </html>

    enter image description here

    We have reported the issue to Microsoft Edge Team but we're not sure if it'll be fixed in a foreseeable period for the new Edge with Chromium is coming.