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] }
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>');
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>
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.