IE 11 onload is never called - javascript

My web page has following javascript
function LoadPDF(filename)
{
var loc = filename;
document.getElementById("pdf").setAttribute("src", loc);
if (window.addEventListener) {
document.getElementById("pdf").addEventListener("load", LoadPrint, false);
}
else if (window.attachEvent) {
document.getElementById("pdf").attachEvent("onload", LoadPrint);
}
else {
document.getElementById("pdf").onload = LoadPrint;
}
}
function LoadPrint() {
alert('fired!');
if (document.getElementById("pdf").src !== "") {
var frm = document.getElementById("pdf");
frm.contentDocument.getElementById("pdf").contentWindow.print();
}
}
The LoadPDF is called from code behind. "pdf" is my iframe. When the pdf is loaded into the iframe I want to call LoadPrint. But the trouble is in IE 11 its never called.
Can anyone please help?

This is an IE11 bug, which MS refuses to fix because they consider it a feature bug and they no longer fix that kind of bugs for old browser versions.
A workaround to this bug, is to load the pdf file inside an other page iframe and then load that page inside your iframe. A simple javascript pdf loader with a file argument:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PDF Loader</title>
<style type="text/css">
html, body {
border:0;
margin:0;
height:100%;
overflow-y:hidden;
}
#pdf {
border:0;
margin:0;
width:100%;
height:100%;
}
</style>
</head>
<body>
<iframe id="pdf"></iframe>
<script type="text/javascript">
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
var pdf = getParameterByName('pdf');
document.getElementById('pdf').setAttribute('src', pdf);
</script>
</body>
</html>
You can use it with the <filename.html>?pdf=<pdf_file_to_load>.
Then you just change your code to load the pdf file through that loader like this:
function LoadPDF(filename)
{
var loc = "pdf-loader.html?pdf="+filename;
document.getElementById("pdf").setAttribute("src", loc);
if (window.addEventListener) {
document.getElementById("pdf").addEventListener("load", LoadPrint, false);
}
else if (window.attachEvent) {
document.getElementById("pdf").attachEvent("onload", LoadPrint);
}
else {
document.getElementById("pdf").onload = LoadPrint;
}
}
function LoadPrint() {
alert('fired!');
}
LoadPDF('http://www.pdf995.com/samples/pdf.pdf');
Now the LoadPrint function is called on iframe load event even on IE11.
Here is my working example you can even test with IE11: http://zikro.gr/dbg/html/ie11-iframe-pdf/
Here you can see a screen capture with the 10MB PDF loading and only after it finish loading it fires the load event and alerts the message:

I don't know if this is your specific issue in this instance, but make sure you bind your listeners to the element before you assign it's src attribute. If the item is in cache it is possible for the load event to fire before you bind to it, thus missing it entirely.

Related

How to catch CORS error while loading external website in iframe [duplicate]

Is there any good way to detect when a page isn't going to display in a frame because of the X-Frame-Options header? I know I can request the page serverside and look for the header, but I was curious if the browser has any mechanism for catching this error.
OK, this one is old but still relevant.
Fact:
When an iframe loads a url which is blocked by a X-Frame-Options the loading time is very short.
Hack:
So if the onload occurs immediately I know it's probably a X-Frame-Options issue.
Disclaimer:
This is probably one of the 'hackiest' code I've written, so don't expect much:
var timepast=false;
var iframe = document.createElement("iframe");
iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;";
iframe.src = "http://pix.do"; // This will work
//iframe.src = "http://google.com"; // This won't work
iframe.id = "theFrame";
// If more then 500ms past that means a page is loading inside the iFrame
setTimeout(function() {
timepast = true;
},500);
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
if(timepast) {
console.log("It's PROBABLY OK");
}
else {
console.log("It's PROBABLY NOT OK");
}
});
}
else {
iframe.onload = function(){
if(timepast) {
console.log("It's PROBABLY OK");
}
else {
console.log("It's PROBABLY NOT OK");
}
};
}
document.body.appendChild(iframe);
Disclaimer: this answer I wrote in 2012(Chrome was version ~20 at that time) is outdated and I'll keep it here for historical purposes only. Read and use at your own risk.
Ok, this is a bit old question, but here's what I found out (it's not a complete answer) for Chrome/Chromium.
the way do detect if a frame pointing to a foreign address has loaded is simply to try to access its contentWindow or document.
here's the code I used:
element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>';
myframe = $(element).find('iframe');
then, later:
try {
var letstrythis = myframe.contentWindow;
} catch(ex) {
alert('the frame has surely started loading');
}
the fact is, if the X-Frame-Options forbid access, then myFrame.contentWindow will be accessible.
the problem here is what I called "then, later". I haven't figured out yet on what to rely, which event to subsribe to find when is the good time to perform the test.
This is based on #Iftach's answer, but is a slightly less hacky.
It checks to see if iframe.contentWindow.length > 0 which would suggest that the iframe has successfully loaded.
Additionally, it checks to see if the iframe onload event has fired within 5s and alerts that too. This catches failed loading of mixed content (in an albeit hacky manner).
var iframeLoaded = false;
var iframe = document.createElement('iframe');
// ***** SWAP THE `iframe.src` VALUE BELOW FOR DIFFERENT RESULTS ***** //
// iframe.src = "https://davidsimpson.me"; // This will work
iframe.src = "https://google.com"; // This won't work
iframe.id = 'theFrame';
iframe.style.cssText = 'position:fixed; top:40px; left:10px; bottom:10px;'
+ 'right:10px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;';
var iframeOnloadEvent = function () {
iframeLoaded = true;
var consoleDiv = document.getElementById('console');
if (iframe.contentWindow.length > 0) {
consoleDiv.innerHTML = '✔ Content window loaded: ' + iframe.src;
consoleDiv.style.cssText = 'color: green;'
} else {
consoleDiv.innerHTML = '✘ Content window failed to load: ' + iframe.src;
consoleDiv.style.cssText = 'color: red;'
}
}
if (iframe.attachEvent){
iframe.attachEvent('onload', iframeOnloadEvent);
} else {
iframe.onload = iframeOnloadEvent;
}
document.body.appendChild(iframe);
// iframe.onload event doesn't trigger in firefox if loading mixed content (http iframe in https parent) and it is blocked.
setTimeout(function () {
if (iframeLoaded === false) {
console.error('%c✘ iframe failed to load within 5s', 'font-size: 2em;');
consoleDiv.innerHTML = '✘ iframe failed to load within 5s: ' + iframe.src;
consoleDiv.style.cssText = 'color: red;'
}
}, 5000);
Live demo here - https://jsfiddle.net/dvdsmpsn/7qusz4q3/ - so you can test it in the relevant browsers.
At time of writing, it works on the current version on Chrome, Safari, Opera, Firefox, Vivaldi & Internet Explorer 11. I've not tested it in other browsers.
The only thing I can think of is to proxy an AJAX request for the url, then look at the headers, and if it doesn't have X-Frame-Options, then show it in the iframe. Far from ideal, but better than nothing.
At least in Chrome, you can notice the failure to load because the iframe.onload event doesn't trigger. You could use that as an indicator that the page might not allow iframing.
Online test tools might be useful.
I used https://www.hurl.it/.
you can clearly see the response header.
Look for X-frame-option. if value is deny - It will not display in iframe.
same origin- only from the same domain,
allow- will allow from specific websites.
If you want to try another tool, you can simply google for 'http request test online'.
This is how I had checked for X-Frames-Options for one of my requirements. On load of a JSP page, you can use AJAX to send an asynchronous request to the specific URL as follows:
var request = new XMLHttpRequest();
request.open('GET', <insert_URL_here>, false);
request.send(null);
After this is done, you can read the response headers received as follows:
var headers = request.getAllResponseHeaders();
You can then iterate over this to find out the value of the X-Frames-Options. Once you have the value, you can use it in an appropriate logic.
This can be achieved through
a) Create a new IFrame through CreateElement
b) Set its display as 'none'
c) Load the URL through the src attribute
d) In order to wait for the iframe to load, use the SetTimeOut method to delay a function call (i had delayed the call by 10 sec)
e) In that function, check for the ContentWindow length.
f) if the length > 0, then the url is loaded else URL is not loaded due to X-Frame-Options
Below is the sample code:
function isLoaded(val) {
var elemId = document.getElementById('ctlx');
if (elemId != null)
document.body.removeChild(elemId);
var obj= document.createElement('iframe');
obj.setAttribute("id", "ctlx");
obj.src = val;
obj.style.display = 'none';
document.body.appendChild(obj);
setTimeout(canLoad, 10000);
}
function canLoad() {
//var elemId = document.getElementById('ctl100');
var elemId = document.getElementById('ctlx');
if (elemId.contentWindow.length > 0) {
elemId.style.display = 'inline';
}
else {
elemId.src = '';
elemId.style.display = 'none';
alert('not supported');
}
}

Run javascript function on loaded page

Very new to Javascript, so working on my first project. Attempting to run a script that gathers listing numbers, opens them in a URL and clicks an element on the loaded page. I can't get .click() to run on the resulting loaded page.
I've tried to set the logIn function to only run once the resulting page has loaded, but it doesn't seem to be doing the trick. AM I missing something basic?
var listingNum = prompt("Listing numbers").split(" ");
logIn = function(){
if(document.readyState === "complete"){
document.getElementById('SignInAsMemberLinkHeader').click();
}
};
for(i = 0; i < listingNum.length; i++){
window.open("http://www.website.com" + listingNum[i],"_self");
setInterval(logIn(), 4000);
};
Okay, the following test harness worked for me. I had to change your _self reference to _blank, so that each page loads separately and doesn't overwrite the operation of the parent page. You then just handle the load event of each window that is instantiated using window.open(). This was the part you were missing. You weren't handling the load events of the loaded windows.
You may wish to check that the SignInAsMemberLinkHeader element exists prior to calling click() on it, but I'll leave that up to you to implement.
NB this will not work if cross site scripting restrictions apply.
Hope this helps :)
<!DOCTYPE HTML>
<html>
<head>
<title>External Page Opener Test</title>
<meta charset="UTF-8">
<style>
body {
background-color:cornflowerblue;
color:white;
font-family:Tahoma,Arial,sans-serif;
}
</style>
<script>
window.addEventListener('load', init, false);
function init(event) {
var listings = prompt("Listing numbers:");
if (listings) {
var listingNum = listings.split(" ");
for (i = 0; i < listingNum.length; i++) {
// I used my local desktop and 3 test HTML files,
//each with a button click and handler on them.
var url = "file:///C:/Users/******/Desktop/" + listingNum[i];
var handle = window.open(url, "_blank");
handle.addEventListener('load', extPageLoaded, false);
}
} else {
console.log('No listings were entered.');
}
}
function extPageLoaded(event) {
const TIME_TO_WAIT_IN_MILLISECONDS = 4000;
setTimeout(
function() {
event.target.getElementById('SignInAsMemberLinkHeader').click();
},
TIME_TO_WAIT_IN_MILLISECONDS
);
}
</script>
</head>
<body>
</body>
</html>

NS_ERROR_UNEXPECTED in Firefox when uploading file from iframe

I'm trying to allow users to upload files without causing the page to change when they upload the files. To do this, I'm using an iframe, which I'm adding a form and a file input to, then submitting the form within the (hidden) iframe. This works just fine on Chrome, but not on Firefox.
Below is code which causes this problem.
<!DOCTYPE html>
<html>
<head>
<style>
#pretty-button { background: blue; }
#hidden-uploader { display: none; }
</style>
<script>
window.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('pretty-button');
var filename_output = document.getElementById('filename');
var upload_iframe = document.getElementById('hidden-uploader');
btn.addEventListener('click', function() {
document.body.appendChild(upload_iframe);
_document = upload_iframe.contentDocument;
var form = _document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('enctype', 'multipart/form-data');
form.setAttribute('action', '.');
var file_input = _document.createElement('input');
file_input.setAttribute('type', 'file');
file_input.setAttribute('name', 'document');
form.appendChild(file_input);
_document.body.appendChild(form);
file_input.click();
file_input.addEventListener('change', function() {
console.log('file selected');
form.submit();
upload_iframe.addEventListener('load', function() {
console.log('file uploaded');
});
});
});
});
</script>
</head>
<body>
<button id="pretty-button">Choose a File</button>
<span id="filename"></span>
<iframe id="hidden-uploader"></iframe>
</body>
</html>
On firefox, this fails with NS_ERROR_UNEXPECTED: on line 33, which is form.submit(), when a file is selected.
Any idea what might be happening here?
I think I figured the problem, which is in the line
document.body.appendChild(upload_iframe);
This causes the iframe to reload itself, which means that the contentDocument of the iframe before it is re-appended to the document body is different from the contentDocument of the iframe after it is re-appended to the document body. The reloading occurs while the file dialog is open.
This can be verified by making the following changes:
<!DOCTYPE html>
<html>
<head>
<style>
#pretty-button { background: blue; }
#hidden-uploader { display: none; }
</style>
<script>
window.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('pretty-button');
var filename_output = document.getElementById('filename');
var upload_iframe = document.getElementById('hidden-uploader');
btn.addEventListener('click', function() {
document.body.appendChild(upload_iframe);
_document = upload_iframe.contentDocument;
var form = _document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('enctype', 'multipart/form-data');
form.setAttribute('action', '.');
var file_input = _document.createElement('input');
file_input.setAttribute('type', 'file');
file_input.setAttribute('name', 'document');
form.appendChild(file_input);
_document.body.appendChild(form);
file_input.click();
// So far, the iframe hasn't reloaded.
file_input.addEventListener('change', function() {
/* Because the iframe loads in less time than it
* takes for the user to select a file, the iframe
* has now reloaded, and _document refers to the
* contentDocument of an iframe which is no longer
* attached to the page.
*/
console.log('file selected');
var _newDocument = upload_iframe.contentDocument;
console.log(_document === _newDocument); // false in Firefox, true in Chrome
form.submit();
upload_iframe.addEventListener('load', function() {
console.log('file uploaded');
});
});
});
});
</script>
</head>
<body>
<button id="pretty-button">Choose a File</button>
<span id="filename"></span>
<iframe id="hidden-uploader"></iframe>
</body>
</html>
By removing the offending line, the above starts working in Firefox.

Why doesn't IE8 handle iframe onload events?

Sample code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function on_iframe_load() {
document.getElementById('iframe_a').onload = function() {
alert('Thanks for the visit!');
};
}
</script>
</head>
<body>
<iframe name="iframe_a" id="iframe_a"></iframe>
Go!
</body>
</html>
It works in all major browsers with no problem, but IE8 (and probably prior versions) don't understand it.
Update: Just came up with a solution, but I'm not sure if it's right coding. Please review:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
var clicked = false;
function activate() {
clicked = true;
}
function pop() {
if (clicked) {
alert('Thanks for the visit!');
};
}
</script>
</head>
<body>
<iframe name="iframe_a" onload="pop();"></iframe>
Go!
</body>
</html>
Using inline attribute on iframe seems to fix this issue in IE8:
<!DOCTYPE html>
<html>
<head>
<title></title>
<script>
function onIframeLoad(iframe) {
if(iframe.src) {
alert('Thanks for the visit!');
}
}
function onLinkClick(url) {
document.getElementById('iframe_a').src = url;
}
</script>
</head>
<body>
<iframe id="iframe_a" onload="onIframeLoad(this);"></iframe>
Go!
</body>
</html>
update by request:
You should try writing more unobtrusive javascript. Writing code in such way may prevent you from such strange bugs in IE.
<!DOCTYPE html>
<html>
<body>
<iframe id="display-frame"></iframe>
Go!
<script>
window.onload = function() {
var iframe = document.getElementById('display-frame'),
link = document.getElementsByTagName('a')[0];
// load handler
function onIframeLoad() {
alert('Thanks for the visit!');
}
// event handlers
if(iframe.addEventListener) iframe.addEventListener('load', onIframeLoad, false);
else if(iframe.attachEvent) iframe.attachEvent('onload', onIframeLoad);
link.onclick = function() {
iframe.src = this.href;
return false;
}
};
</script>
</body>
</html>
It seems you can't add a load listener to an iFrame in IE using the DOM property once the page has loaded.
But you can use attachEvent, so:
function on_iframe_load() {
function foo() {
alert('Thanks for the visit!');
};
var el = document.getElementById('iframe_a');
if (el.attachEvent) {
el.attachEvent('onload',foo);
} else if (el.addEventListener) {
el.addEventListener('load', 'foo', false);
}
}
I was testing in IE 6 and reversed the usual test order so that attachEvent is used in preference to addEventListener. You may want to test more recent versions of IE to see if the opposite order works and also test other IE–like browsers such as Opera.
Edit
Modified the code after testing (silly me) to use addEventListener. Here's something that works in IE and others:
function on_iframe_load() {
function foo() {
alert('Thanks for the visit!');
};
var el = document.getElementById('iframe_a');
if (el.attachEvent) {
el.attachEvent('onload',foo);
} else {
el.onload = foo;
}
}
And if you use an onload attribute in the markup, you don't need to add the listener using script.
It works :)
tested on IE8, ff, chrome
var iframe = document.getElementById('iframeid');
if (iframe .attachEvent) {
iframe .attachEvent('onload',alert("IE Iframe loaded"));
} else {
iframe .onload = alert("Other than IE Iframe loaded");
}
Just use jquery:
$(iframe).bind( 'load', function(){} );

will HTML <body> onLoad events overwrite javascript window onload event?

I have a HTML page and a javascript function is attached to the <body> onLoad event.
I wanted to show up a message dialog when the page loads. I cannot edit the javascript function attached to this onLoad event due to some reasons.
So I created a new javascript file with a single function which will show the message dialog. Then I added this line in my javascript file
window.onload = onPageLoad;
onPageLoad() is my function which could show the message dialog.
I attached this javascript file in my HTML using script tag. When I run this HTML file, onPageLoad() function is not getting called.
I want to know whether <body> tag, onLoad event overrides the window onload. If so, can someone help me in implementing this functionality somehow.
Please keep in mind that I could not edit my HTML file and I could write only new javascript file. Thanks.
Depends on browser. window.onload currently overwrites body onload in Chrome, Firefox and Safari on OSX
You can ADD your function to the onload:
window.onload = function() {
alert('window.onload')
}
if (window.addEventListener) {
window.addEventListener('load', function() {
alert('addEventListener')
}, false);
} else if (window.attachEvent) { // IE < 9
window.attachEvent('onload', function() {
alert('attachEvent')
});
}
<body onload="alert('body onload')">
</body>
AND/OR Replace
var bodyOnload = document.body.onload;
window.onload = function() {
alert('window.onload')
bodyOnload()
}
if (window.addEventListener) {
window.addEventListener('load', function() {
alert('addEventListener')
}, false);
} else if (window.attachEvent) { // IE < 9
window.attachEvent('onload', function() {
alert('attachEvent')
});
}
<body onload="alert('body onload')">
</body>

Categories