How can I handle errors in loading an iframe? - javascript

I have an <iframe> that other sites can include so their users can POST a form back to my site. I'd like to handle gracefully the cases where my site is down or my server can't serve the <iframe> contents (that is, a response timeout or a 4xx or 5xx error). I tried adding an onError to the <iframe> object, but that didn't seem to do anything:
showIFrame = function() {
var iframe = document.createElement('iframe');
iframe.id = 'myIFrame';
iframe.src = 'http://myserver.com/someURLThatFailsToLoad';
iframe.onError = iframe.onerror = myHandler;
document.body.appendChild(iframe);
};
myHandler = function(error) {
document.getElementById('myIFrame').style.display = 'none';
console.error('Error loading iframe contents: ' + error);
return true;
};
If my server returns a 404 I just get the contents of the not-found page in my <iframe>. In fact, that error handler isn't ever triggered. Is there a way to make this work?
(I'm currently testing in Chrome, but I'd like it to also work for FF and IE >= 7.)

To detect whether your server is down or not, you can include an empty script file from your own domain. When the server is down, the onerror event handler will fire:
var el = document.createElement('script');
el.onerror = errorFunction;
el.src = "somebogusscript.js?" + new Date().getTime();
document.body.appendChild(el);
Note: don't forget to add a random string to the src attribute to avoid the client using a cached version (which could stop a look at the server at all).

Perhaps you could try onErrorUpdate for the event handler? I couldn't see an onError handler for iFrames. If that doesn't work, you could try onLoad and then check the source of the iframe or the title of it for a 404 message.
Such as:
if (frameDoc.title == 'title the server sends for 404') {
Source:
http://bytes.com/topic/javascript/answers/166288-catch-404-when-using-iframe
iFrame Methods: http://www.java2s.com/Code/HTMLCSSReference/HTML-Tag-Reference/iframeJavaScriptMethods.htm
iFrame Properties: http://www.java2s.com/Code/HTMLCSSReference/HTML-Tag-Reference/iframeJavaScriptProperties.htm

One technique is to set a JavaScript timeout when you make the request. If your timeout fires before the iframe onload event, the content didn't load. You could then set iframe.src to about:blank, delete, or reuse the iframe.

Related

javascript iframe set timer and check if loaded

I need to trigger a url validation check onclick of the url before loading the page. If the url is not valid or cannot be reached I need to display an alert.
When I use i.onload it keeps waiting for it to load. If it never loads it also never produces an error to be caught by i.onerror. If the link loads properly everything works well.
html:
<a id={UrlToTest} onClick={this.testUrl}>{UrlToTest}</a>
javascript:
testURL(e) {
var targetURL = e.target.id;
var i = document.createElement('iframe');
i.style.display = 'none';
i.src = targetURL;
document.body.appendChild(i);
i.onload = function() {
//setTimeout(function(){
i.parentNode.removeChild(i);
return window.open(targetURL, '_blank');
//}, 5000);
};
i.onerror = function(){
alert('The link didn"t load');
};
}
If I insert console.log's it remains waiting for onload to trigger. If I allow the link to open without testing in a hidden iframe it will display 'unable to connect' immediately, or 404 error, etc. This error is never received when checked within the iframe.
Welcome to Stack Overflow :)
I believe your issue is that you set your onload and onerror after you set the src.
Think of it this way - your browser is trying to load (or error) the iframe as soon as possible, once the src is set, the browser starts his work, if an error (or success) is thrown before the onload was set, there's nothing to catch it.
TLDR - I think that switching the order (setting onload and onerror first) should resolve your problem.
Edit --
So I misunderstood the question, yes there are situations where nothing comes back from the iframe, specifically I could reproduce that with this code on the console here in stack overflow:
var targetURL = 'localhost:1'
var i = document.createElement('iframe');
i.onload = function() {
alert('The link did load');
};
i.onerror = function(){
alert('The link did NOT load');
};
i.src = targetURL;
document.body.appendChild(i);
the above code will not fire any event.
I'm not aware of why this is exactly happening, but maybe you should use a setTimeout timer to timeout the whole operation
let timer = setTimeout(() => {
alert('Error opening page');
}, 5000);
var targetURL = 'localhost:1'
var i = document.createElement('iframe');
i.onload = function() {
alert('The link did load');
clearTimeout(timer);
};
i.onerror = function(){
alert('The link did NOT load');
clearTimeout(timer);
};
i.src = targetURL;
document.body.appendChild(i);
I dug a bit deeper, turns out there's a bug for Chrome on this matter
https://bugs.chromium.org/p/chromium/issues/detail?id=365457
Unfortunately it seems that 'this is the spec', from the bug report:
I have discussed this with Adam Barth, and we have confirmed that the
behaviour described here is the behaviour described in the Living HTML
specification.
As follows: The specification requires that all HTML elements support
on onerror event. However, it does NOT require that all elements
supporting network fetches raise fire a simple event called onerror.
That is, elements must support allowing applications to set error
handlers, but there is no (generic) requirement that the event be
raised, in either HTML or the Fetch specification.

Access an Iframe variable from parent window

I have a webpage at url https://parent.com and it has an iframe injected into it with source https://iframe.com. Iframe has a global variable defined called iframe_variable. I want to access the iframe_variable from parent document.
I know browsers don't allow cross origin communication and they provide a postMessage API to do it securely.
Constraint: I do not have access to any of parent or iframe code.
On Browser console, I somehow want to access iframe_variable
I have tried the following:
Get reference of iframe first.
var iframe = document.getElementsByTagName('iframe')[0]; // There is only one iframe on document
Create a listener for message event posted from parent window.
var iframeListener = function(e) {
console.log("Got message from parent");
e.source.postMessage(JSON.stringify({'IFRAME_VARIABLE': window.IFRAME_VARIABLE}));
}
Create a listener for parent window to accept 'message' posted from iframe.
parentListener = function(e) {
console.log('Got message from iframe');
var data = JSON.parse(e.data);
window.VARIABLE = data.IFRAME_VARIABLE;
}
Attach parent_listener to message event.
window.addEventListener('message', parentListener, false);
Now if i try to post a message to iframe from parent as follows:
iframe.contentWindow.postMessage('test message', '*')
It doesn't trigger 'iframeListener'. The reason is because it is not registered against the message event in iframe.
I don't think I can even do that from the browser console when I am on parent.com as any attempt to do iframe.contentWindow.addEventListener will result in an error as it will be an attempt to access a different domain.
Is there a workaround that? Is there anything that I am missing in my understanding and research.
P.S: I have not written the origin checks for simplicity. I know I must check for the origin a message is posted from. Not doing that leaves a huge security hole.

Display error when iframe refuse to display [duplicate]

I am using Knockout.js to bind iframe src tag(This will be configurable with respect to User).
Now, if user has configured http://www.google.com (I know it won't load in iframe, thats why I am using it for -ve scenario) and that has to be shown in IFrame.
but it throws error:-
Refused to display 'http://www.google.co.in/' in a frame because it
set 'X-Frame-Options' to 'SAMEORIGIN'.
I have the following code for Iframe:-
<iframe class="iframe" id="iframe" data-bind="attr: {src: externalAppUrl, height: iframeheight}">
<p>Hi, This website does not supports IFrame</p>
</iframe>
What I want is, if the URL fails to load. I want to display Custom Message.
FIDDLE HERE
Now, if I use onload and onerror as:-
<iframe id="browse" style="width:100%;height:100%" onload="alert('Done')" onerror="alert('Failed')"></iframe>
It works fine loading w3schools.com but not with google.com.
Secondly:- if I make it as a function and try like I have done in my fiddle, it doesn't works.
<iframe id="browse" style="width:100%;height:100%" onload="load" onerror="error"></iframe>
I don't know how should I make it run and capture the error.
Edited:- I have seen Want to call a function if iframe doesn't load or load's question in stackoverflow but it shows error for sites that can be loaded in iframe.
Also, I have looked into Stackoverflow iframe on load event
Thanks!!
You wont be able to do this from the client side because of the Same Origin Policy set by the browsers. You wont be able to get much information from the iFrame other than basic properties like its width and height.
Also, google sets in its response header an 'X-Frame-Options' of SAMEORIGIN.
Even if you did an ajax call to google you wont be able to inspect the response because the browser enforcing Same Origin Policy.
So, the only option is to make the request from your server to see if you can display the site in your IFrame.
So, on your server.. your web app would make a request to www.google.com and then inspect the response to see if it has a header argument of X-Frame-Options. If it does exist then you know the IFrame will error.
I think that you can bind the load event of the iframe, the event fires when the iframe content is fully loaded.
At the same time you can start a setTimeout, if the iFrame is loaded clear the timeout alternatively let the timeout fire.
Code:
var iframeError;
function change() {
var url = $("#addr").val();
$("#browse").attr("src", url);
iframeError = setTimeout(error, 5000);
}
function load(e) {
alert(e);
}
function error() {
alert('error');
}
$(document).ready(function () {
$('#browse').on('load', (function () {
load('ok');
clearTimeout(iframeError);
}));
});
Demo: http://jsfiddle.net/IrvinDominin/QXc6P/
Second problem
It is because you miss the parens in the inline function call; try change this:
<iframe id="browse" style="width:100%;height:100%" onload="load" onerror="error"></iframe>
into this:
<iframe id="browse" style="width:100%;height:100%" onload="load('Done func');" onerror="error('failed function');"></iframe>
Demo: http://jsfiddle.net/IrvinDominin/ALBXR/4/
The onload will always be trigger, i slove this problem use try catch block.It will throw an exception when you try to get the contentDocument.
iframe.onload = function(){
var that = $(this)[0];
try{
that.contentDocument;
}
catch(err){
//TODO
}
}
This is a slight modification to Edens answer - which for me in chrome didn't catch the error. Although you'll still get an error in the console:
"Refused to display 'https://www.google.ca/' in a frame because it set 'X-Frame-Options' to 'sameorigin'." At least this will catch the error message and then you can deal with it.
<iframe id="myframe" src="https://google.ca"></iframe>
<script>
myframe.onload = function(){
var that = document.getElementById('myframe');
try{
(that.contentWindow||that.contentDocument).location.href;
}
catch(err){
//err:SecurityError: Blocked a frame with origin "http://*********" from accessing a cross-origin frame.
console.log('err:'+err);
}
}
</script>
I solved it with window.length.
But with this solution you can take current error (X-Frame or 404).
iframe.onload = event => {
const isLoaded = event.target.contentWindow.window.length // 0 or 1
}
MSDN
Update:
contentWindow.name will now always throw an error on cross-origin frames.
Seems like the only way is to do this server side (for now).
I have written a small cloudflare worker to capture headers for remote apis and it can be used here to check for X-Frame-Options.
Sample code to check before rendering in iframe: (jsfiddle: https://jsfiddle.net/2gud39aw/2/)
function checkUrlFrameOptions(apiurl){
return fetch("https://header-inspector.repalash.workers.dev/?" + new URLSearchParams({
'apiurl': apiurl,
'headers': 'x-frame-options'
}), {
method: 'GET'
}).then(r => r.json()).then(json => {
let xFrameOp = (json.headers['x-frame-options'] || '').toLowerCase();
// deny all requests
if(xFrameOp==='deny') return false;
// deny if different origin
if(xFrameOp==='sameorigin' && json.origin !== location.origin) return false;
return true;
})
}
checkUrlFrameOptions("https://google.com").then((res)=>console.log("google.com can be loaded in iframe: ", res))
checkUrlFrameOptions("https://example.com").then((res)=>console.log("example.com can be loaded in iframe: ", res))
The cloudflare worker endpoint ( https://header-inspector.repalash.workers.dev ) is just for testing, don't use this in production. The code is available at: https://gist.github.com/repalash/b1e778dbe3ac2e7149831c530a6535f9
and can be deployed directly as a cloudflare worker
OLD Answer
Here's a simple solution, tested on Chrome and Safari.
const iframe = document.createElement('iframe')
iframe.onload = function() {
try {
iframe.contentWindow.name
} catch (e) {
if (e.message.includes('cross-origin')) console.warn(e.message);
else console.error(e.message);
}
}
iframe.src = "https://google.com";
jsFiddle demo: https://jsfiddle.net/k5e1mg3t/5/
I faced similar problem. I solved it without using onload handler.I was working on AngularJs project so i used $interval and $ timeout. U can also use setTimeout and setInterval.Here's the code:
var stopPolling;
var doIframePolling;
$scope.showIframe = true;
doIframePolling = $interval(function () {
if(document.getElementById('UrlIframe') && document.getElementById('UrlIframe').contentDocument.head && document.getElementById('UrlIframe').contentDocument.head.innerHTML != ''){
$interval.cancel(doIframePolling);
doIframePolling = undefined;
$timeout.cancel(stopPolling);
stopPolling = undefined;
$scope.showIframe = true;
}
},400);
stopPolling = $timeout(function () {
$interval.cancel(doIframePolling);
doIframePolling = undefined;
$timeout.cancel(stopPolling);
stopPolling = undefined;
$scope.showIframe = false;
},5000);
$scope.$on("$destroy",function() {
$timeout.cancel(stopPolling);
$interval.cancel(doIframePolling);
});
Every 0.4 Seconds keep checking the head of iFrame Document. I somthing is present.Loading was not stopped by CORS as CORS error shows blank page.
If nothing is present after 5 seconds there was some error (Cors policy) etc..
Show suitable message.Thanks. I hope it solves your problem.
As explained in the accepted answer, https://stackoverflow.com/a/18665488/4038790, you need to check via a server.
Because there's no reliable way to check this in the browser, I suggest you build yourself a quick server endpoint that you can use to check if any url is loadable via iframe. Once your server is up and running, just send a AJAX request to it to check any url by providing the url in the query string as url (or whatever your server desires). Here's the server code in NodeJs:
const express = require('express')
const app = express()
app.get('/checkCanLoadIframeUrl', (req, res) => {
const request = require('request')
const Q = require('q')
return Q.Promise((resolve) => {
const url = decodeURIComponent(req.query.url)
const deafultTimeout = setTimeout(() => {
// Default to false if no response after 10 seconds
resolve(false)
}, 10000)
request({
url,
jar: true /** Maintain cookies through redirects */
})
.on('response', (remoteRes) => {
const opts = (remoteRes.headers['x-frame-options'] || '').toLowerCase()
resolve(!opts || (opts !== 'deny' && opts !== 'sameorigin'))
clearTimeout(deafultTimeout)
})
.on('error', function() {
resolve(false)
clearTimeout(deafultTimeout)
})
}).then((result) => {
return res.status(200).json(!!result)
})
})
app.listen(process.env.PORT || 3100)

Problems with window.postMessage on Chrome

I have been stuck on this for hours.
I have a.html on http://example.com that contains an iframe with src to
b.html on http://subdomain.example.com. a.html has some JS code
to postMessage to the iframe.
The code to postMessage is simple:
iframe_window.postMessage('message', iframe_element.src)
But this way, Chrome throws an error:
Unable to post message to http://subdomain.example.com. Recipient has origin null.
I have also tried:
iframe_window.postMessage('message', 'http://subdomain.example.com')
But NO LUCK!
This is the ONLY WAY it works:
iframe_window.postMessage('message', '*')
But I have heard '*' is not good to use.
No problems in Firefox.
It looks like this might be an issue with the child iframe not being loaded at the time the signal is sent, thus iframe.src doesn't have the proper value.
I did some testing and got the same error as you, but when I wrapped the postMessage call in a setTimeout and waited 100ms then there was no error, which tells me that this is an initialisation race condition.
Here's how I implemented a cleaner solution without the setTimeout:
Parent:
window.addEventListener("DOMContentLoaded", function() {
var iframe = document.querySelector("iframe")
, _window = iframe.contentWindow
window.addEventListener("message", function(e) {
// wait for child to signal that it's loaded.
if ( e.data === "loaded" && e.origin === iframe.src.split("/").splice(0, 3).join("/")) {
// send the child a message.
_window.postMessage("Test", iframe.src)
}
})
}, false)
Child:
window.addEventListener("DOMContentLoaded", function() {
// signal the parent that we're loaded.
window.parent.postMessage("loaded", "*")
// listen for messages from the parent.
window.addEventListener("message", function(e) {
var message = document.createElement("h1")
message.innerHTML = e.data
document.body.appendChild(message)
}, false)
}, false)
This is a simple solution in which the child will signal to anyone that it's loaded (using "*", which is okay, because nothing sensitive is being sent.) The parent listens for a loaded event and checks that it's the child that it's interested in that's emitting it.
The parent then sends a message to the child, which is ready to receive it. When the child gets the message it puts the data in an <h1> and appends that to the <body>.
I tested this in Chrome with actual subdomains and this solution worked for me.
A shorter solution is to wrap the postMessage inside iframe_element.onload function.

Detect failure to load contents of an iframe

I can detect when the content of an iframe has loaded using the load event. Unfortunately, for my purposes, there are two problems with this:
If there is an error loading the page (404/500, etc), the load event is never fired.
If some images or other dependencies failed to load, the load event is fired as usual.
Is there some way I can reliably determine if either of the above errors occurred?
I'm writing a semi-web semi-desktop application based on Mozilla/XULRunner, so solutions that only work in Mozilla are welcome.
If you have control over the iframe page (and the pages are on the same domain name), a strategy could be as follows:
In the parent document, initialize a variable var iFrameLoaded = false;
When the iframe document is loaded, set this variable in the parent to true calling from the iframe document a parent's function (setIFrameLoaded(); for example).
check the iFrameLoaded flag using the timer object (set the timer to your preferred timeout limit) - if the flag is still false you can tell that the iframe was not regularly loaded.
I hope this helps.
This is a very late answer, but I will leave it to someone who needs it.
Task: load iframe cross-origin content, emit onLoaded on success and onError on load error.
This is the most cross browsers origin independent solution I could develop. But first of all I will briefly tell about other approaches I had and why they are bad.
1. iframe That was a little shock for me, that iframe only has onload event and it is called on load and on error, no way to know it is error or not.
2. performance.getEntriesByType('resource'). This method returns loaded resources. Sounds like what we need. But what a shame, firefox always adds Resource in resources array no matter it is loaded or failed. No way to know by Resource instance was it success. As usual. By the way, this method does not work in ios<11.
3. script I tried to load html using <script> tag. Emits onload and onerror correctly, sadly, only in Chrome.
And when I was ready to give up, my elder collegue told me about html4 tag <object>. It is like <iframe> tag except it has fallbacks when content is not loaded. That sounds like what we are need! Sadly it is not as easy as it sounds.
CODE SECTION
var obj = document.createElement('object');
// we need to specify a callback (i will mention why later)
obj.innerHTML = '<div style="height:5px"><div/>'; // fallback
obj.style.display = 'block'; // so height=5px will work
obj.style.visibility = 'hidden'; // to hide before loaded
obj.data = src;
After this we can set some attributes to <object> like we'd wanted to do with iframe. The only difference, we should use <params>, not attributes, but their names and values are identical.
for (var prop in params) {
if (params.hasOwnProperty(prop)) {
var param = document.createElement('param');
param.name = prop;
param.value = params[prop];
obj.appendChild(param);
}
}
Now, the hard part. Like many same-like elements, <object> doesn't have specs for callbacks, so each browser behaves differently.
Chrome. On error and on load emits load event.
Firefox. Emits load and error correctly.
Safari. Emits nothing....
Seems like no different from iframe, getEntriesByType, script....
But, we have native browser fallback! So, because we set fallback (innerHtml) directly, we can tell if <object> is loaded or not
function isReallyLoaded(obj) {
return obj.offsetHeight !== 5; // fallback height
}
/**
* Chrome calls always, Firefox on load
*/
obj.onload = function() {
isReallyLoaded(obj) ? onLoaded() : onError();
};
/**
* Firefox on error
*/
obj.onerror = function() {
onError();
};
But what to do with Safari? Good old setTimeout.
var interval = function() {
if (isLoaded) { // some flag
return;
}
if (hasResult(obj)) {
if (isReallyLoaded(obj)) {
onLoaded();
} else {
onError();
}
}
setTimeout(interval, 100);
};
function hasResult(obj) {
return obj.offsetHeight > 0;
}
Yeah.... not so fast. The thing is, <object> when fails has unmentioned in specs behaviour:
Trying to load (size=0)
Fails (size = any) really
Fallback (size = as in innnerHtml)
So, code needs a little enhancement
var interval = function() {
if (isLoaded) { // some flag
return;
}
if (hasResult(obj)) {
if (isReallyLoaded(obj)) {
interval.count++;
// needs less then 400ms to fallback
interval.count > 4 && onLoadedResult(obj, onLoaded);
} else {
onErrorResult(obj, onError);
}
}
setTimeout(interval, 100);
};
interval.count = 0;
setTimeout(interval, 100);
Well, and to start loading
document.body.appendChild(obj);
That is all. I tried to explain code in every detail, so it may look not so foolish.
P.S. WebDev sucks
I had this problem recently and had to resort to setting up a Javascript Polling action on the Parent Page (that contains the IFRAME tag). This JavaScript function checks the IFRAME's contents for explicit elements that should only exist in a GOOD response. This assumes of course that you don't have to deal with violating the "same origin policy."
Instead of checking for all possible errors which might be generated from the many different network resources.. I simply checked for the one constant positive Element(s) that I know should be in a good response.
After a pre-determined time and/or # of failed attempts to detect the expected Element(s), the JavaScript modifies the IFRAME's SRC attribute (to request from my Servlet) a User Friendly Error Page as opposed to displaying the typical HTTP ERROR message. The JavaScript could also just as easily modify the SRC attribute to make an entirely different request.
function checkForContents(){
var contents=document.getElementById('myiframe').contentWindow.document
if(contents){
alert('found contents of myiframe:' + contents);
if(contents.documentElement){
if(contents.documentElement.innerHTML){
alert("Found contents: " +contents.documentElement.innerHTML);
if(contents.documentElement.innerHTML.indexOf("FIND_ME") > -1){
openMediumWindow("woot.html", "mypopup");
}
}
}
}
}
I think that the pageshow event is fired for error pages. Or if you're doing this from chrome, then your check your progress listener's request to see if it's an HTTP channel in which case you can retrieve the status code.
As for page dependencies, I think you can only do this from chrome by adding a capturing onerror event listener, and even then it will only find errors in elements, not CSS backgrounds or other images.
Doesn't answer your question exactly, but my search for an answer brought me here, so I'm posting just in case anyone else had a similar query to me.
It doesn't quite use a load event, but it can detect whether a website is accessible and callable (if it is, then the iFrame, in theory, should load).
At first, I thought to do an AJAX call like everyone else, except that it didn't work for me initially, as I had used jQuery. It works perfectly if you do a XMLHttpRequest:
var url = http://url_to_test.com/
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status != 200) {
console.log("iframe failed to load");
}
};
xhttp.open("GET", url, true);
xhttp.send();
Edit:
So this method works ok, except that it has a lot of false negatives (picks up a lot of stuff that would display in an iframe) due to cross-origin malarky. The way that I got around this was to do a CURL/Web request on a server, and then check the response headers for a) if the website exists, and b) if the headers had set x-frame-options.
This isn't a problem if you run your own webserver, as you can make your own api call for it.
My implementation in node.js:
app.get('/iframetest',function(req,res){ //Call using /iframetest?url=url - needs to be stripped of http:// or https://
var url = req.query.url;
var request = require('https').request({host: url}, function(response){ //This does an https request - require('http') if you want to do a http request
var headers = response.headers;
if (typeof headers["x-frame-options"] != 'undefined') {
res.send(false); //Headers don't allow iframe
} else {
res.send(true); //Headers don't disallow iframe
}
});
request.on('error',function(e){
res.send(false); //website unavailable
});
request.end();
});
Have a id for the top most (body) element in the page that is being loaded in your iframe.
on the Load handler of your iframe, check to see if getElementById() returns a non null value.
If it is, iframe has loaded successfully. else it has failed.
in that case, put frame.src="about:blank". Make sure to remove the loadhandler before doing that.
If the iframe is loaded on the same origin as the parent page, then you can do this:
iframeEl.addEventListener('load', function() {
// NOTE: contentDocument is null if a connection error occurs or if
// X-Frame-Options is not SAMESITE (which could happen with
// 4xx or 5xx error pages if the corresponding error handlers
// do not specify SAMESITE). If error handlers do not specify
// SAMESITE, then networkErrorOccurred will incorrectly be set
// to true.
const networkErrorOccurred = !iframeEl.contentDocument;
const serverErrorOccurred = (
!networkErrorOccurred &&
!iframeEl.contentDocument.querySelector('#well-known-element')
);
if (networkErrorOccurred || serverErrorOccurred) {
let errorMessage;
if (networkErrorOccurred) {
errorMessage = 'Error: Network error';
} else if (serverErrorOccurred) {
errorMessage = 'Error: Server error';
} else {
// Assert that the above code is correct.
throw new Error('networkErrorOccurred and serverErrorOccurred are both false');
}
alert(errorMessage);
}
});

Categories

Resources