I've a problem...I use jQuery ajax to call a web service that returns XML. The jQuery ajax stuff works awesome for every browser except for ie.
So for ie browsers, I am using XDomainRequest. Here is the code:
if ($.browser.msie && window.XDomainRequest) {
// Use Microsoft XDR
var xdr = new XDomainRequest();
xdr.open("get", theUserUrl);
xdr.timeout = 95000;
xdr.onerror = function () {
console.log('we have an error!');
}
xdr.onprogress = function () {
console.log('this sucks!');
};
xdr.ontimeout = function () {
console.log('it timed out!');
};
xdr.onopen = function () {
console.log('we open the xdomainrequest');
};
xdr.onload = function () {
// XDomainRequest doesn't provide responseXml, so if you need it:
var xml2 = new ActiveXObject("Microsoft.XMLDOM");
xml2.async = false;
xml2.loadXML(xdr.responseText);
console.log('do we get any response text at all?: ' + xdr.responseText);
ParseOwnershipObjects(xml2);
//AddServiceRequestsToMap(xml2, map, spinner);
};
xdr.send();
}
This exact code works fine elsewhere in the application with a
different url.
The url is fine, it returns exactly what it should in the browser
(and hence why the jquery ajax call works). Couple of things to
note:
I am integrating my own html/javascript with another guy's asp.net
project.
In the global.asax.cs file, I have:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,OPTIONS");
}
so I don't think that it's a header problem.
None of my handlers fire. Not the onprogress, ontimeout, onerror...nothing!
I don't have time to convert the web service to JSON.
Any thoughts?
Thanks!
Disclaimer - I actually haven't used 'XDomainRequest' - when using jQ I set data to jsonp for xdomain requests...
When debugging - are you using IE Dev tools (F12)? If not, the error is likely console.log
EDIT:
mea culpa, disregard the jsonp stuff - missed the part you mentioned XML
Update:
Out of curiosity I'm trying XDomainRequest. I copied your code and just added a value for theUserUrl.
as above/expected, unless I have Internet Explorer Developer tools running, console is undefined - and may give the impression that "none of your handlers are firing".
Once I have the IE dev tools enabled (docked or otherwise) xdr.onerror fires. we have an error is logged in the IE console. So while there is an error, the handler does fire.
A quick read on XDomainRequest requires the responding server to have the Access-Control-Allow-Origin header. I'm calling my own server and I know I don't have this header set, so without further debugging, it would be a good guess that's why xdr.onerror is being fired.
As it turns out, there were special characters in the url parameters that were not being correctly dealt with by the XDomainRequest object. Instead of the GET request, I am going to use the POST request on internet explorer-only queries.
EDIT - I ended up switching the web service over to return output in JSON format, thus negating the need for the XDomainRequest. Using JSON speeds things up a bit too, I recommend it!
Related
I am trying to access the HTML Geolocation API available in Android WebView (using SDK version 24).
The main problem is that the call to navigator.geolocation.getCurrentPosition() in JavaScript never returns (neither with an error, nor with position data), while on application side I check for permissions and properly pass them to WebView using android.webkit.GeolocationPermissions.Callback class.
UPDATE: Just to clarify here, by "never returns" I mean that none of the two supplied callbacks navigator.geolocation.getCurrentPosition(success, error) are ever called.
In a sample app I built to test this (with just one small activity hosting WebView) I declare the permissions in manifest and request them properly on App start. I see the prompt and can grant or deny permission to location information.
Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Code in the main form:
public boolean checkFineLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION) && !mIsPermissionDialogShown) {
showPermissionDialog(R.string.dialog_permission_location);
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_ACCESS_FINE_LOCATION);
}
return false;
} else {
return true;
}
}
I can check for permissions during runtime using Context.checkSelfPermission() and I see that the respective permissions are granted to my app.
Then I try to open a web page in a WebView control.
I enable all required options in the settings:
mWebSettings.setJavaScriptEnabled(true);
mWebSettings.setAppCacheEnabled(true);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setGeolocationEnabled(true);
mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
mWebSettings.setSupportZoom(true);
I use the following WebChromeClient overload for handling geolocation requests from JavaScript:
protected class EmbeddedChromeClient extends android.webkit.WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
android.webkit.GeolocationPermissions.Callback callback) {
// do we need to request permissions ?
if (ContextCompat.checkSelfPermission(EmbeddedBrowserActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// this should never happen, it means user revoked permissions
// need to warn and quit?
callback.invoke(origin, false, false);
}
else {
callback.invoke(origin, true, true);
}
}
}
To test this I use the following code (taken from Mozilla API help page, shortened here):
function geoFindMe() {
function success(position) {}
function error() {}
navigator.geolocation.getCurrentPosition(success, error);
}
What I see is that the call tonavigator.geolocation.getCurrentPosition(success, error) in JavaScript never returns. I see that onGeolocationPermissionsShowPrompt() method in Java gets properly called and as I check for permissions there I always get the result 0, i.e. PackageManager.PERMISSION_GRANTED, so callback.invoke(origin, true, true) is executed on every call. If I try several times, I see several calls to my Java code. Still, nothing happens on the JavaScript side here after I call invoke().
I added the code to check for granted permissions using the invocation of getOrigins(ValueCallback<Set<String>> callback) in GeolocationPermissions class, as described here in the documentation. I see in the callback that my origins are allowed to request locations (they are listed in the set).
Any ideas what might be wrong here?
Try with options to set timeout (source):
var options = {
enableHighAccuracy: true,
timeout: 10000,
maximumAge: 0
};
navigator.geolocation.getCurrentPosition(success, error, options);
If it fails then try to override getCurrentPosition (source):
(function() {
if (navigator.geolocation) {
function PositionError(code, message) {
this.code = code;
this.message = message;
}
PositionError.PERMISSION_DENIED = 1;
PositionError.POSITION_UNAVAILABLE = 2;
PositionError.TIMEOUT = 3;
PositionError.prototype = new Error();
navigator.geolocation._getCurrentPosition = navigator.geolocation.getCurrentPosition;
navigator.geolocation.getCurrentPosition = function(success, failure, options) {
var successHandler = function(position) {
if ((position.coords.latitude == 0 && position.coords.longitude == 0) ||
(position.coords.latitude == 37.38600158691406 && position.coords.longitude == -122.08200073242188))
return failureHandler(new PositionError(PositionError.POSITION_UNAVAILABLE, 'Position unavailable'));
failureHandler = function() {};
success(position);
}
var failureHandler = function(error) {
failureHandler = function() {};
failure(error);
}
navigator.geolocation._getCurrentPosition(successHandler, failureHandler, options);
window.setTimeout(function() { failureHandler(new PositionError(PositionError.TIMEOUT, 'Timed out')) }, 10000);
}
}
})();
As a third option annotate with #JavascriptInterface (source) in EmbeddedChromeClient
Also add at the proper place in your code:
mWebSettings.setJavaScriptEnabled(true);
//...
mWebSettings.setSupportZoom(true);
webView.addJavascriptInterface(new EmbeddedChromeClient(webView), "injectedObject");
webView.loadData("html here", "text/html", null);
The last option is just to use tags in html, load the html from disk storage, replace tags in the calling function, load the html/string in the webView. I have used this approach before in Android when positioning frustrated me too much. Then you don't have to worry about https either.
Looks like there are 2 different issues in your case:
getCurrentPosition never fails
getCurrentPosition never succeed
First point could be just because method has infinite timeout
The default value is Infinity, meaning that getCurrentPosition() won't return until the position is available.
Second point could be tricky, there is a param maximumAge which means
The PositionOptions.maximumAge property is a positive long value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return. If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position. If set to Infinity the device must return a cached position regardless of its age.
0 by default means that device won't use cached position and will try to fetch the real one and it could be an issue for long response.
Also you could check this reporst which could mean that this API doesn't work really good on Android:
https://github.com/ionic-team/ionic-native/issues/1958
https://issues.apache.org/jira/browse/CB-13241
*Cordova leaves geolocation stuff for browser.
Change your request for permission like this,
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
},0);
This seems to work.
Actually, navigator is a child of browser global object, the window. you should first access to window then call the navigator. In some modern browsers, In addition to the window, some child object is presented like a global object, for example: location, navigator and etc.
The WebView has no global object window. So you can add it manually, for this action please read this medium article.
Maybe your code will be like below:
my_web_view.evaluateJavascript("javascript: " + "updateFromAndroid(\"" + edit_text_to_web.text + "\")", null);
And then add JavaScript interface, like the window object, to this evaluator:
my_web_view.addJavascriptInterface(JavaScriptInterface(), JAVASCRIPT_OBJ); //JAVASCRIPT_OBJ: like window, like navigator, like location and etc.
For applications targeting Android N and later SDKs (API level > Build.VERSION_CODES.M), the method onGeolocationPermissionsShowPrompt (String origin, GeolocationPermissions.Callback callback) is only called for requests originating from secure origins such as HTTPS. On non-secure origins, geolocation requests are automatically denied.
You could narrow down your problem by yourself if you had tried putting a breakpoint or a log inside the method.
You have two options:
Target a lower level API, which is obviously much easier but not really appreciated.
Set up SSL in your website.
In case some of you are still experiencing this issue, I was able to get the navigator.geolocation.getCurrentPosition() to work for me by setting some values for the options parameter, as follows:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
async (p) => {
await this.workMyCurrentPosition(p);
},
(e) => this.navigatorError(e),
{ timeout: 7000, enableHighAccuracy: true, maximumAge: 0 }
);
}
Hope it works for you!
There is an extensive post on this subject:
navigator.geolocation.getCurrentPosition sometimes works sometimes doesn't
Apparently the solution is to check on navigator.geolocation then make the call:
if(navigator.geolocation) { // dummy call
navigator.geolocation.getCurrentPosition(success, error)
}
I experienced this problem on Android 8. The error callback was called with error.code==1 "PERMISSION_DENIED".
https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only
Geolocation API Removed from Unsecured Origins in Chrome 50
Meaning, the URL of your app must begin with https:// for the call to work.
This question already has answers here:
Detect the Internet connection is offline?
(22 answers)
Closed 8 years ago.
How do you check if there is an internet connection using jQuery? That way I could have some conditionals saying "use the google cached version of JQuery during production, use either that or a local version during development, depending on the internet connection".
The best option for your specific case might be:
Right before your close </body> tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
This is probably the easiest way given that your issue is centered around jQuery.
If you wanted a more robust solution you could try:
var online = navigator.onLine;
Read more about the W3C's spec on offline web apps, however be aware that this will work best in modern web browsers, doing so with older web browsers may not work as expected, or at all.
Alternatively, an XHR request to your own server isn't that bad of a method for testing your connectivity. Considering one of the other answers state that there are too many points of failure for an XHR, if your XHR is flawed when establishing it's connection then it'll also be flawed during routine use anyhow. If your site is unreachable for any reason, then your other services running on the same servers will likely be unreachable also. That decision is up to you.
I wouldn't recommend making an XHR request to someone else's service, even google.com for that matter. Make the request to your server, or not at all.
What does it mean to be "online"?
There seems to be some confusion around what being "online" means. Consider that the internet is a bunch of networks, however sometimes you're on a VPN, without access to the internet "at-large" or the world wide web. Often companies have their own networks which have limited connectivity to other external networks, therefore you could be considered "online". Being online only entails that you are connected to a network, not the availability nor reachability of the services you are trying to connect to.
To determine if a host is reachable from your network, you could do this:
function hostReachable() {
// Handle IE and more capable browsers
var xhr = new ( window.ActiveXObject || XMLHttpRequest )( "Microsoft.XMLHTTP" );
// Open new request as a HEAD to the root hostname with a random param to bust the cache
xhr.open( "HEAD", "//" + window.location.hostname + "/?rand=" + Math.floor((1 + Math.random()) * 0x10000), false );
// Issue request and handle response
try {
xhr.send();
return ( xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304) );
} catch (error) {
return false;
}
}
You can also find the Gist for that here: https://gist.github.com/jpsilvashy/5725579
Details on local implementation
Some people have commented, "I'm always being returned false". That's because you're probably testing it out on your local server. Whatever server you're making the request to, you'll need to be able to respond to the HEAD request, that of course can be changed to a GET if you want.
Ok, maybe a bit late in the game but what about checking with an online image?
I mean, the OP needs to know if he needs to grab the Google CMD or the local JQ copy, but that doesn't mean the browser can't read Javascript no matter what, right?
<script>
function doConnectFunction() {
// Grab the GOOGLE CMD
}
function doNotConnectFunction() {
// Grab the LOCAL JQ
}
var i = new Image();
i.onload = doConnectFunction;
i.onerror = doNotConnectFunction;
// CHANGE IMAGE URL TO ANY IMAGE YOU KNOW IS LIVE
i.src = 'http://gfx2.hotmail.com/mail/uxp/w4/m4/pr014/h/s7.png?d=' + escape(Date());
// escape(Date()) is necessary to override possibility of image coming from cache
</script>
Just my 2 cents
5 years later-version:
Today, there are JS libraries for you, if you don't want to get into the nitty gritty of the different methods described on this page.
On of these is https://github.com/hubspot/offline. It checks for the connectivity of a pre-defined URI, by default your favicon. It automatically detects when the user's connectivity has been reestablished and provides neat events like up and down, which you can bind to in order to update your UI.
You can mimic the Ping command.
Use Ajax to request a timestamp to your own server, define a timer using setTimeout to 5 seconds, if theres no response it try again.
If there's no response in 4 attempts, you can suppose that internet is down.
So you can check using this routine in regular intervals like 1 or 3 minutes.
That seems a good and clean solution for me.
You can try by sending XHR Requests a few times, and then if you get errors it means there's a problem with the internet connection.
I wrote a jQuery plugin for doing this. By default it checks the current URL (because that's already loaded once from the Web) or you can specify a URL to use as an argument. Always doing a request to Google isn't the best idea because it's blocked in different countries at different times. Also you might be at the mercy of what the connection across a particular ocean/weather front/political climate might be like that day.
http://tomriley.net/blog/archives/111
i have a solution who work here to check if internet connection exist :
$.ajax({
url: "http://www.google.com",
context: document.body,
error: function(jqXHR, exception) {
alert('Offline')
},
success: function() {
alert('Online')
}
})
Sending XHR requests is bad because it could fail if that particular server is down. Instead, use googles API library to load their cached version(s) of jQuery.
You can use googles API to perform a callback after loading jQuery, and this will check if jQuery was loaded successfully. Something like the code below should work:
<script type="text/javascript">
google.load("jquery");
// Call this function when the page has been loaded
function test_connection() {
if($){
//jQuery WAS loaded.
} else {
//jQuery failed to load. Grab the local copy.
}
}
google.setOnLoadCallback(test_connection);
</script>
The google API documentation can be found here.
A much simpler solution:
<script language="javascript" src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
and later in the code:
var online;
// check whether this function works (online only)
try {
var x = google.maps.MapTypeId.TERRAIN;
online = true;
} catch (e) {
online = false;
}
console.log(online);
When not online the google script will not be loaded thus resulting in an error where an exception will be thrown.
strophe.flxhr.js
/* flXHR plugin
**
** This plugin implements cross-domain XmlHttpRequests via an invisible
** Flash plugin.
**
** In order for this to work, the BOSH service *must* serve a
** crossdomain.xml file that allows the client access.
**
** flXHR.js should be loaded before this plugin.
*/
Strophe.addConnectionPlugin('flxhr', {
init: function () {
// replace Strophe.Request._newXHR with new flXHR version
// if flXHR is detected
if (flensed && flensed.flXHR) {
Strophe.Request.prototype._newXHR = function () {
var xhr = new flensed.flXHR({
autoUpdatePlayer: true,
instancePooling: true,
noCacheHeader: false});
xhr.onreadystatechange = this.func.prependArg(this);
return xhr;
};
} else {
Strophe.error("flXHR plugin loaded, but flXHR not found." +
" Falling back to native XHR implementation.");
}
}
});
This is a code provided by a book from which I am trying to learn XMPP programming with JavaScript and jQuery. It also uses strophe.js and flXHR.js. strophe.flxhr.js is used as script file in the main app. But while running the app in my FireFox browser, Web Console is giving me the error TypeError: this.func.prependArg is not a function. Also I am using WebStorm IDE and it shows Unresolved function or method prependArg(). But according to the book, this should run. What wrong am I doing?
Please Help. Thank you.
Apparently, there was a fault with the strophe.flxhr.js file. It was a very old version (6 years old). There is a new version of this in github here.
There is a slight change in the code, and this is working. No errors are thrown by the web console. This is the new code:
strophe.flxhr.js:
/* flXHR plugin
**
** This plugin implements cross-domain XmlHttpRequests via an invisible
** Flash plugin.
**
** In order for this to work, the BOSH service *must* serve a
** crossdomain.xml file that allows the client access.
**
** flXHR.js should be loaded before this plugin.
*/
Strophe.addConnectionPlugin('flxhr', {
init: function (conn) {
// replace Strophe.Request._newXHR with new flXHR version
// if flXHR is detected
if (flensed && flensed.flXHR) {
Strophe.Request.prototype._newXHR = function () {
var xhr = new flensed.flXHR({
autoUpdatePlayer: true,
instancePooling: true,
noCacheHeader: false,
onerror: function () {
conn._changeConnectStatus(Strophe.Status.CONNFAIL,
"flXHR connection error");
conn._onDisconnectTimeout();
}});
xhr.onreadystatechange = this.func.bind(null, this);
return xhr;
};
} else {
Strophe.error("flXHR plugin loaded, but flXHR not found." +
" Falling back to native XHR implementation.");
}
}
});
EDIT:
From the developer of this script, Jack Moffitt:
"This code no longer works. strophe.flxhr.js just makes some testing easier as it relaxes the CORS requirement by using Flash instead. Most things support CORS natively now, so it is probably not needed anyway. It doesn't provide any APIs or anything that are needed by the example code; it's purely an alternate implementation of XMLHttpRequest. If you can make the newer version work, then use it.".
Here is the conversation.
How I can read WebSocket frames of a web page in a Chrome extension or Firefox add-on, in a way that cannot be detected by the page?
Inspect WebSockets frames from a Chrome Dev Tools extension formulates a similar question, but developing a NPAPI plugin no longer makes sense because it will soon be removed.
Intercepting the WebSocket data is easy. Simply execute the following script before the page constructs the WebSocket. This snippet monkey-patches the WebSocket constructor: When a new WebSocket constructor is created, the snippet subscribes to the message event, from where you can do whatever you want with the data.
This snippet is designed to be indistinguishable from native code so the modification cannot easily be detected by the page (however, see the remarks at the end of this post).
(function() {
var OrigWebSocket = window.WebSocket;
var callWebSocket = OrigWebSocket.apply.bind(OrigWebSocket);
var wsAddListener = OrigWebSocket.prototype.addEventListener;
wsAddListener = wsAddListener.call.bind(wsAddListener);
window.WebSocket = function WebSocket(url, protocols) {
var ws;
if (!(this instanceof WebSocket)) {
// Called without 'new' (browsers will throw an error).
ws = callWebSocket(this, arguments);
} else if (arguments.length === 1) {
ws = new OrigWebSocket(url);
} else if (arguments.length >= 2) {
ws = new OrigWebSocket(url, protocols);
} else { // No arguments (browsers will throw an error)
ws = new OrigWebSocket();
}
wsAddListener(ws, 'message', function(event) {
// TODO: Do something with event.data (received data) if you wish.
});
return ws;
}.bind();
window.WebSocket.prototype = OrigWebSocket.prototype;
window.WebSocket.prototype.constructor = window.WebSocket;
var wsSend = OrigWebSocket.prototype.send;
wsSend = wsSend.apply.bind(wsSend);
OrigWebSocket.prototype.send = function(data) {
// TODO: Do something with the sent data if you wish.
return wsSend(this, arguments);
};
})();
In a Chrome extension, the snippet can be run via a content script with run_at:'document_start', see Insert code into the page context using a content script.
Firefox also supports content scripts, the same logic applies (with contentScriptWhen:'start').
Note: The previous snippet is designed to be indistinguishable from native code when executed before the rest of the page. The only (unusual and fragile) ways to detect these modifications are:
Pass invalid parameters to the WebSocket constructor, catch the error and inspecting the implementation-dependent (browser-specific) stack trace. If there is one more stack frame than usual, then the constructor might be tampered (seen from the page's perspective).
Serialize the constructor. Unmodified constructors become function WebSocket() { [native code] }, whereas a patched constructor looks like function () { [native code] } (this issue is only present in Chrome; in Firefox, the serialization is identical).
Serialize the WebSocket.prototype.send method. Since the function is not bound, serializing it (WebSocket.prototype.send.toString()) reveals the non-native implementation. This could be mitigated by overriding the .toString method of .send, which in turn can be detected by the page by a strict comparison with Function.prototype.toString. If you don't need the sent data, do not override OrigWebSocket.prototype.send.
There is an alternative to Rob W's method that completely masks any interaction with the page (for Chrome)
Namely, you can take out some heavy artillery and use chrome.debugger.
Note that using it will stop you from opening Dev Tools for the page in question (or, more precisely, opening the Dev Tools will make it stop working, since only one debugger client can connect). This has been improved since: multiple debuggers can be attached.
This is a pretty low-level API; you'll need to construct your queries using the debugger protocol yourself. Also, the corresponding events are not in the 1.1 documentation, you'll need to look at the development version.
You should be able to receive WebSocket events like those and examine their payloadData:
{"method":"Network.webSocketFrameSent","params":{"requestId":"3080.31","timestamp":18090.353684,"response":{"opcode":1,"mask":true,"payloadData":"Rock it with HTML5 WebSocket"}}}
{"method":"Network.webSocketFrameReceived","params":{"requestId":"3080.31","timestamp":18090.454617,"response":{"opcode":1,"mask":false,"payloadData":"Rock it with HTML5 WebSocket"}}}
This extension sample should provide a starting point.
In fact, here's a starting point, assuming tabId is the tab you're interested in:
chrome.debugger.attach({tabId:tab.id}, "1.1", function() {
chrome.debugger.sendCommand({tabId:tabId}, "Network.enable");
chrome.debugger.onEvent.addListener(onEvent);
});
function onEvent(debuggeeId, message, params) {
if (tabId != debuggeeId.tabId)
return;
if (message == "Network.webSocketFrameSent") {
// do something with params.response.payloadData,
// it contains the data SENT
} else if (message == "Network.webSocketFrameReceived") {
// do something with params.response.payloadData,
// it contains the data RECEIVED
}
}
I have tested this approach (with the linked sample modified as above) and it works.
Just to add an exception to #Xan answer (I don't have enough rep to post a comment on his answer so I add it here cause I believe it can save some time to someone else).
That example won't work if the WebSocket connection is established in a context that was loaded via about:, data: and blob: schemes.
See here for the related bugs: Attach debugger to worker from chrome devtools extension
I tried to do a simple AJAX request on http://localhost:8080/ and I get an error right away when using IE 11. I don't think IE is even trying to send anything.
Did somebody meet this issue?
Here is a fiddle showing this behavior,
html:
<button id='btn1'>launch</button>
onLoad:
var xhr,btn=document.getElementById('btn1');
btn.onclick=onButton;
var onReadyState=function(){
console.log('ready state:'+_xhr.readyState);
if(xhr.readyState===4){
console.log('status:'+_xhr.status);
}
}
function onButton(){
xhr=new window.XMLHttpRequest();
xhr.onreadystatechange=onReadyState;
xhr.open('POST','http://localhost:8080/ScanAPI/v1/client');
xhr.send();
}
You will need to launch the IE F12 developer tool, before trying and you will see IE catching the exception.
Any help on this would be greatly appreciated.
Thanks!
It doesn't work because you are referencing an object named _xhr that does not exist within the scope of the onReadyState function.
You should be using this instead :
var onReadyState = function() {
if (this.readyState === 4) {
console.log('status :' + this.status);
}
};
That's because the XMLHttpRequest object will call back onReadyState with its own context, which is accessible through this in your function.
Also note that the onReadyState function misses a semi-colon at the end of its definition, didn't notice it at first sight.
EDIT : I also noticed that IE10 (and IE11) does interpret some HTTP response code as network errors (such as with a 401 response code), if it is your case, then it makes sense that IE fails at retrieving your resource.
I forked your fiddle and wrote a simple page that works well with IE11.