Access denied in IE 10 and 11 when ajax target is localhost - ajax

I'm trying to do a ajax call between a server (http) that is on internet. And target that to my own localhost. FF/Chrome/ ETC... works. It's ONLY an IE issue. IM USING IE 11 AND 10.
The request is don't even done. The "denied access" is thrown instantly.
This is the code. Just for you to see.
Is not the classical HTTP/HTTPS error in IE8 AND IE9. This is something else, but the documentation is not helpful.
$jq.ajax({
contentType: 'application/json',
url: url,
dataType: 'json',
crossDomain: true,
beforeSend: function (xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + $jq.base64.encode(username and password));
},
success: function (data, status, headers) {},
error: function (xhr, status, error) {}
The status is 0 in xhr object and error is "Denied access"

Internet Explorer raises this error as part of its security zones feature. Using default security settings, an "Access is Denied" error is raised when attempting to access a resource in the "Local intranet" zone from an origin in the "Internet" zone.
If you were writing your Ajax code manually, Internet Explorer would raise an error when you try to open the resource. For example:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost/', true); // This line will trigger an error
xhr.send();
You can work around this error by adding the origin site to the "Trusted sites" security zone. You can test this by adding "http://client.cors-api.appspot.com" to your "Trusted sites" zone and using this test page at test-cors.org with your localhost site as the Remote URL.

In addition to the trusted site requirement I found that the problem was not fixed until I used the same protocol for the request as my origin, e.g. my test site was hosted on a https but failed with any destination using http (without the s).
This only applies to IE, Chrome just politely logs a warning in the debug console and doesn't fail.

If you are attempting to make cross-origin ajax requests in IE9, you'll need to use XDomainRequest instead of XMLHttpRequest. There is a jQuery plug-in that wraps XDR. You should be aware that there are some notable limitations of XDR.
Another option would be to use a library like this: https://github.com/jpillora/xdomain.

jQuery implements ajax calls using the XMLHttpRequest object which is not supported in IE9. You have to force it to use XDomainRequest instead.
I get around this problem using this jQuery plugin:
https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest

Note:
Do not use "http://www.domain.xxx" or "http://localhost/" or "IP" for URL in Ajax.
Only use path(directory) and page name without address.
false state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
true state:
var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true); // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);
function createAjax()
{
var ajaxHttp = null;
try
{
if(typeof ActiveXObject == 'function')
ajaxHttp = new ActiveXObject("Microsoft.XMLHTTP");
else
if(window.XMLHttpRequest)
ajaxHttp = new XMLHttpRequest();
}
catch(e)
{
alert(e.message);
return null;
}
//-------------
return ajaxHttp;
};

Related

Ajax calls from node to django

I'm developing a django system and I need to create a chat service that was in real-time. For that I used node.js and socket.io.
In order to get some information from django to node I made some ajax calls that worked very nice when every address was localhost, but now that I have deployed the system to webfaction I started to get some errors.
The djando server is on a url like this: example.com and the node server is on chat.example.com. When I make a ajax get call to django I get this error on the browser:
XMLHttpRequest cannot load http://chat.example.com/socket.io/?EIO=3&transport=polling&t=1419374305014-4. Origin http://example.com is not allowed by Access-Control-Allow-Origin.
Probably I misunderstood some concept but I'm having a hard time figuring out which one.
The snippet where I think the problem is, is this one:
socket.on('id_change', function(eu){
sessionid = data['sessionid']
var options = {
host: 'http://www.example.com',
path: '/get_username/',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': sessionid.length
}
}
var request = http.request(options, function(response) {
response.on('data', function(msg){
console.log('Received something')
if(response.statusCode == 200){
//do something here
}
}
})
})
request.write(sessionid);
request.end();
});
And I managed to serve socket.io.js and make connections to the node server, so this part of the setup is ok.
Thank you very much!
You're bumping into the cross origin resource sharing problem. See this post for more information: How does Access-Control-Allow-Origin header work?
I am NOT a Django coder at all, but from this reference page (https://docs.djangoproject.com/en/1.7/ref/request-response/#setting-header-fields) it looks like you need to do something like this in the appropriate place where you generate responses:
response = HttpResponse()
response['Access-Control-Allow-Origin'] = 'http://chat.example.com'

HTTPS Ajax request failure when SSL Certificate changed

In our system we have a case, when SSL certificate changed in backend, and as you can imagine Ajax requests are not working after that.
Ext.Ajax.request({
url : 'myaction',
method : 'POST',
success : function(response, options) {
// some code here
},
failure : function(response, options) {
// when SSL changed request failed
}
});
In response we have no additional data to understand if the problem is because of SSL change.
What I want to do?
If there will is any option to understand if failure because of SSL changing I will be able to show some message and then just reload the page to allow user accept new one.

xhr sending requests to specific port?

I am very new to ajax development, I am trying to use xhr to get and post data,the problem is when I use port based requests?
here is my working code and not working codes
$.ajax({
url : "login.php",
type : "post",
data : {
userProfile : JSON.stringify(data)
},
success : handleDBResponse,
error : function(jqXHR, textStatus,errorThrown) {
console.log("The following error occured: "+ textStatus,errorThrown);
},
complete : function() {
// console.log("user authentication
// successful.")
}
});
this works good, but when I am using native xhr with url:port getting no response.
function reqListener () {
console.log(this.responseText);
};
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "http://www.domain.com:443/akorp.css", true);
oReq.send();
It's not working, I was debugged and I found request status is cancelled.
.htaccess file included
Access-Control-Allow-Origin:*
still I am getting the error
www.domain.com:443 not allowed by www.domain.com Access-Control-Allow-Origin etc..
what are the possible causes for this error and how to properly send request to port?
443 is the HTTPS port. Perhaps you should try an HTTPS URL instead of forcing the port.
I'm not sure I want to know why you're pulling a CSS file from somebody else's serer with xhr.

Using ajax to GET a token from external site returns empty response

I have two sites right now. One that has a token and one that is supposed to allow a user to do stuff with the token.
When I visit the first site that has the token, mySite.local/services/session/token it shows it: OTV4Gu9VQfjIo2ioQ0thajdEJ6nEINoxsLuwgT_6S0w
When I am on the page that is supposed to GET this token, I get an empty response and the error for the ajax function is thrown.
The weird part is that when investigating the issue with firebug, I can see the response for the ajax request is 43B - the same size as the token. So for some reason the page with the token is being hit properly, but the response is not coming through.
Here is a screenshot of the firebug response:
And here is the JQuery with the ajax request:
var nid; //global node id variable
$('html').click(function(){
try {
$.ajax({
url:"http://mySite.local/services/session/token",
type:"get",
dataType:"text",
error:function (jqXHR, textStatus, errorThrown) {
alert('error thrown - ' + errorThrown);
console.log(JSON.stringify(jqXHR));
console.log(JSON.stringify(textStatus));
console.log(JSON.stringify(errorThrown));
},
success: function (token) {
//Do some stuff now that token is received
}
});
}
catch (error) {
alert("page_dashboard - " + error);
}
});
Your running into the Same Origin Policy which essentially states any request done by client side/browser language like Javascript must be on the same port, with the same domain name and the same protocol. In your case http://mysitemobile.local does not equal http://mysite.local so you're request is being blocked. Firebug's way of displaying that is no response with 43 bytes.
There are two ways to work around this, Cross-origin resource sharing (CORS) or JSONP. CORS is a HTTP header that is added to the server you are requesting to and provides a whitelist of acceptable domains that are allowed break the same origin policy. Most recent browsers support this header.
The other option is JSONP, wraps a JSON object into a Javascript function that is called using <script> tags normally. If the other server returns {status: 0} and you have a function called parseStatus() in your code that the remote server would wrap into parseStatus({status:0}); thus calling your function without having to worry about the same origin policy.

Securing (ssl) a nodejs/express web service and calling it cross-domain with $.ajax()

I've set up a nodejs app like this:
var express = require('./../../../Library/node_modules/express');
var https = require('https');
var app = express();
httpsOptions = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem') // SELF-SIGNED CERTIFICATE
}
var server = https.createServer(httpsOptions);
app.get('/myservice', function(req, res) {
...
}
server.listen(8443);
I have opened the 8443 port in my server for inbound requests.
From a browser, if I open https://mydomain/myservice:8443 I get the untrusted connection warning from the browser, which seems logical.
Then from a test.html that I run from my local computer (to test the cross-domain issue), I do something like this:
function testService(){
var data = { some JSON };
$.ajax({
url: 'https://myserver:8443/myservice',
dataType: "jsonp",
data: data,
jsonpCallback: "_mycallback",
cache: false,
timeout: 5000,
success: function(data) {
alert(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error: ' + textStatus + " " + errorThrown);
}
});
}
My problem is that this request times out, and I don't think it even reaches the service.
Any idea why?
Whenever I make this request reach the server, hopefully thanks to your kind responses, what will happen with the browser warning for the untrusted certificate? Will that stop $.ajax() from silently calling the server and receiving the response?
The reason that your clients' JSONP request times out could be practically anything. Because of the way JSONP works, you can only ever know whether the request fails or succeeds, and when it fails it will always be because of a timeout. That said, its pretty much guaranteed to fail if you haven't saved the servers self-signed cert on the client. To do so, make sure that you tell your browser to always trust the servers' certificate. In Firefox you can also go Preferences->Encryption->View Certificates->Your Certificates->Import... to add the certificate to Firefox. Other browsers should have a similar interface.
To solve a potential cross domain issue, try adding the following to your app.get('/myservice'):
res.header("Access-Control-Allow-Origin:", "*");
res.header("Access-Control-Allow-Methods:", "GET");
Additionally, different browsers handle these things differently. In my experience Firefox is sometimes more lenient than Chrome, but I would definitely test in both.
To test the HTTPS issue, first I would try just setting up a regular expressjs server (no encryption) and not using https:// in your request. If the request then succeeds you know that the problem is the SSL. If so, make sure that when your browser gives a security warning you enable any options allowing you to permanently add that site to your trusted hosts.
Also, I believe that this line:
var server = https.createServer(httpsOptions);
should be:
var server = https.createServer(httpsOptions, app);
(From: http://expressjs.com/api.html#app.listen)
You may also want to add the following code below var server = https.createServer(httpsOptions); for debugging (so that you can easily see if your server receives the request):
app.get('*', function(req, res, next) {
// You *should* also be able to add the response headers here, although I haven't tried.
console.log('Request received', req, res);
next();
})
Hopefully that helps!

Resources