I'm trying to fecth data from a REST webservice into a HTML page. The problem is Internet Explorer 6 (which is my target station on XP SP3) that I'm struggling to make work.
Here's the code used :
$.ajax({
type: "GET",
contentType:"application/json; charset=utf-8",
dataType : 'json',
url: "https://jsonplaceholder.typicode.com/posts/1",
success: function(data) {
alert(data);
},
complete: function(xhr) {
alert(xhr.status+" "+xhr.responseText);
}
});
Tested on Firefox 52 ESR : both success and complete functions works.
On Chrome 49 : success works, complete is called but xhr.status is 0 and xhr.responseText is empty.
On IE6 success is not called at all and complete is called but xhr.status is 0 and xhr.responseText is undefined.
Tried what was already answered here on SOF like removing extra commas, adding dataType ... but still no success with IE6.
How can we do it once for all ?
Thanks
IE6 is ancient, it does not support CORS (not even with XDomainRequest).
There is no way to perform cross-origin RESTful HTTP requests with JavaScript in IE6.
If you want to perform a cross-origin request, then you will need to use some other (non-RESTful) approach such as JSONP.
As Quentin said, sending CORS request is not supported in IE 6/7, you could check this blog.
You could refer to the following code to use JSONP.
// Using JSONP
$.ajax({
url: "<request url>",
jsonp: "callback",
// Tell jQuery we're expecting JSONP
dataType: "jsonp",
data: {
q: "select title,abstract,url from search.news where query=\"cat\"",
format: "json"
},
// Work with the response
success: function( response ) {
console.log( response ); // server response
}
});
Besides, please check this article:
Internet Explorer 9 and earlier ignores Access-Control-Allow headers and by default prohibits cross-origin requests for Internet Zone. To enable cross-origin access go to Tools->Internet Options->Security tab, click on “Custom Level” button. Find the Miscellaneous -> Access data sources across domains setting and select “Enable” option.
Related
Fellas,
I'm trying to do an ajax call to get some JSON. I can get around the cross origin issues in Chrome very easily but in IE the only way I got it working without throwing an error is using JSONP. My problem is that i don't know how to process the response. I can see that the call executes and it returns JSON in fiddler but how do i catch it and play with it in my code that's below.
$.support.cors = true;
function callAjaxIE(){
$.ajax({
type: 'GET',
async: true,
url: usageUrl,
dataType: 'jsonp',
crossDomain: true,
jsonp: false,
jsonpCallback: processDataIE,
// cache: false,
success: function (data) {
alert('success');
//processData(data)
},
error: function (e){
console.log(e);
}
}).done(function (data) {
alert('done');
});
function processDataIE(){
alert('processing data ie');
}
It works when i run it, it displays a message box saying 'processing data ie' but so what. How do i play with the results?
UPDATE:
So I've updated the code as per Quentin. It doesn't go into the 'success' block. It errors out with the following.
When i look at fiddler. The JSON is there. How do i get it?
Don't force the function name. That's a recipe for race conditions. Remove jsonpCallback: processDataIE. Let jQuery determine the function name.
Don't remove the callback parameter from the URL. Make the server read callback from the query string to determine which function to call. Remove jsonp: false,.
Use the success function as normal. (Get rid of processDataIE, that's what success is for).
Asides:
crossDomain: true is pointless. It tells jQuery that when it is using XHR (which you aren't) and the URL is pointing to the same origin (which it isn't) then it should not add extra headers in case the server does an HTTP redirect to a different origin.
async: true is pointless. That's the default, and JSONP requests can't be anything other than async anyway.
$.support.cors = true; is pointless at best and can be harmful. Remove it.
Don't override jQuery's detection of support for CORS by the browser. You can't make ancient browsers support CORS by lying to jQuery. You're using JSONP anyway, so CORS is irrelevant.
The above is the sensible, standard, robust solution.
If you want the quick hack that maintains all the bad practises you have in play, then just look at the first argument to processDataIE.
I'm using cordova and dust.js (HTML templating) in my app. I make Ajax requests that return json objects.
Platforms the App is working on:
--Android browser,FF, chrome and Apk
--iPhone
--PC firefox and IE11 (1 out of 3 pc's wasn't able to make the ajax calls too)
--Windows phone 8 app
Problem:
When I try the windows phone 8 internet explorer, no ajax calls succeed in my app.
Details and solutions I tried
1- The json response is returned correctly as I checked the server log that the ajax call is made to...
2- This problem happens in GET requests as well as POST requests...
3- The ajax is not excuting neither the done nor the fail:
$.ajax({
type: httpMethod,
url: host + url,
data: data,
async: asyncFlag,
dataType: "json",
error: errFn,
dataFilter: dataFilter,
success: (successFn),
timeout: 60000
}).done(function(msg) {
alert( "done" );
}).fail(function() {
alert( "error" );
});
4- I tried adding cache:false in the above request, didn't solve the problem.
We try to put some data to our server, the serverside should be okay because we tested already with DEV HTTP CLIENT Chrome extension. This is our code, I think it should work but I don't know how I could fix the cross domain error.
$.ajax({
type: "PUT",
url: '...../add?callback=JSONPCallback',
contentType: "application/jsonp; charset=utf-8",
data: JSON.stringify({
"name": "Test",
}),
jsonpCallback: "JSONPCallback",
crossDomain: true,
success: function (result) {
console.log('Success!');
},
error: function (a, b, c) {
console.error(a + " " + b + " " + c);
},
fail: function (e) {
alert('fail');
}
});
}
In the GET requests we used 'dataType: 'jsonp' ', but this is not working for PUT . Is there any possibility to PUT a json object and GET a jsonp object back in the success method?
JSONP is a GET operation (specifically, one created via a script tag).
You can do cross-domain PUT, just not in the JSONP way. Your target server has to allow your origin via Cross Origin Resource Sharing (and your browser has to support CORS with XMLHttpRequest, not the IE8 and IE9 XDomainRequest object — although if you need IE8 and IE9 support, if you look around you can find a plugin for jQuery that makes jQuery use XDomainRequest on those browsers).
If you are using modern browser (i.e. Firefox and chrome, safari), you can use HTML5 API CORS for doing this.
Here is the link for Using cors
I want to call the following web service
var url = 'search.php',
data = {
addressdetails: 1,
format: 'json',
osmtype: 'node',
q: 'london'
};
$.ajax('//open.mapquestapi.com/nominatim/v1/' + url, {
type: 'GET',
data: data,
contentType: 'application/json',
success: function (data, status) {
var results = [];
if (status === 'success' && !data.error) {
console.log('success');
}
},
error: function(jqXHR, textStatus, errorThrown ) {
console.log('error');
}
});
I created a JSFiddle with this example: http://jsfiddle.net/JX27m/1
I've been told that IE8+ supports Cross-Origin Resource Sharing (CORS), so there should be a way to tweak this code to make it work on IE9, right?
Cheers,
Christophe
Check CanIUse.com and you will see IE 8 & 9 have partial support. My guess is because CORS was not actually introduced as CORS in the specification till 2009 (after IE 8 & too late to appear in IE 9). They probably implemented support of Access Control for Cross-Site Requests That eventually became CORS. They seem to support the XDomainRequest Object for cross domain requests. Check the Can I Use resources tab to find some other articles.
Assuming the server in question supports CORS and allows your origin, you can use IE's XDomainRequest object rather than XMLHttpRequest. jQuery doesn't do that for you because the jQuery team feel there are too many problems with the XDR object (details in this ticket, near the bottom), but you can do it yourself, or there are plugins for jQuery that provide that functionality. For instance, this one is linked from that same jQuery ticket.
I'm sending data cross domain via a POST request but the response isn't working, specifically, jQuery's success handler never gets called.
Stuff being used: Django, Apache, jQuery.
So, I set up a request rather similar to this:
$.ajax({
url: "http://somesite.com/someplace",
type: "POST",
cache: false,
dataType: "json",
data: { ... },
success: function( msg ) {
alert(msg);
},
});
As you well know, CORS allows me to respond to an OPTIONS query appropriately to say "Yes, you can POST to me". Which I'm doing. Firebug confirms I'm getting my 200 status code and that the return type is in fact application/json. However, Firebug also confirms that the success handler in the above is not being called.
For reference, my response to OPTIONS is:
elif request.method == "OPTIONS":
response = HttpResponse("")
response['Access-Control-Allow-Origin'] = "*"
response['Access-Control-Allow-Methods'] = "POST, GET, OPTIONS"
response['Access-Control-Allow-Headers'] = "X-Requested-With"
return response
In contrast, if I set up a complete: function()... handler it works.
So, question is: what's happening (or not) and why? I am getting data fine, I'd just like to be able to return the response.
Update: This fixes my issue on some browsers but since I don't have a complete definite explanation to this behaviour I'm leaving it open.
Ok, so I read the manual and what I understand of it, the algorithm applied is roughly this:
User agents may implement a preflight call. This is the OPTIONS request. The idea is that they make this request which gives them an answer with respect to the requested resource, which they are then supposed to cache. I'm not passing back a max-age field, so I suspect whilst success is being returned and the X-request allowed, there is nothing in the user agent's cache which permitted me to make it, so the default rules (isolate the request) are applied.
When you make the actual request, I believe the user agent is supposed to inspect the pre-flight cache for permissions. Without my max-age field, I believe it isn't finding these permissions. However, responding with the same headers on POST appears to allow Firefox and Google Chrome to view the response. Opera can not. IE remains untested at the moment.
I do not currently understand and it is not clear from the manual (to me at least) whether a CORS request should also answer with these headers in the request as well as the OPTIONS. I shall experiment with the Max-Age header and see what that allows or does not allow. However, I'm still short of some definite authoritative understanding on the issue so if there is someone on here who knows, I'm all ears.
Ok, so I believe the correct way to do things is this:
if request.method == "POST":
response = HttpResponse(simplejson.dumps(data),mimetype='application/json')
response['Access-Control-Allow-Origin'] = "*"
return response
elif request.method == "OPTIONS":
response = HttpResponse("")
response['Access-Control-Allow-Origin'] = "*"
response['Access-Control-Allow-Methods'] = "POST, OPTIONS"
response['Access-Control-Allow-Headers'] = "X-Requested-With"
response['Access-Control-Max-Age'] = "1800"
else:
return HttpResponseBadRequest()
This is based on the documentation I dug up from Mozilla on preflighted requests.
So, what I believe will happen is this:
If there's nothing in the preflight cache, OPTIONS is sent with X-Requested-With set to XMLHttpRequest I believe this is necessary to allow Javascript access to anything, along with an Origin header.
The server can examine that information. That is the security of CORS. In my case, I'm responding with "any origin will do" and "you're allowed to send the X-Requested-With thing". I'm saying that OPTIONS and POST are allowed and that this response should be cached for 30 mins.
The client then goes ahead and makes the POST, which was working before.
I modified the response originally to include Allow-Methods and Allow-Headers but according to the exchange in the above linked documentation this isn't needed. This makes sense, the access check has already been done.
I believe then that what happens is the resource sharing check described here. Basically, once said request has been made, the browser again checks the Allow-Origin field for validity, this being on the request such as POST. If this passes, the client can have access to the data, if not, the request has already completed but the browser denies the actual client side application (Javascript) access to that data.
I believe that is a correct summary of what is going on and in any case it appears to work. If I'm not right, please shout.
For any future searchers who may come across this posting, the following resource is the W3C 2008 working-draft which discusses CORS in-depth.
http://www.w3.org/TR/2008/WD-access-control-20080912/
As of the time of this posting, it should be noted that Chromium specifically, and probably all of WebKit has a bug which prevents the Access-Control-Max-Age header's value from being honored. Details on this can be found on the discussion page for Chromium Issue 131368. In summary - as of now, WebKit-based browsers will override whatever the server returns as a value here with 600 (10 minutes).
REQUEST:
$.ajax({
url: "http://localhost:8079/students/add/",
type: "POST",
crossDomain: true,
data: JSON.stringify(somejson),
dataType: "json",
success: function (response) {
var resp = JSON.parse(response)
alert(resp.status);
},
error: function (xhr, status) {
alert("error");
}
});
RESPONSE:
response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")
return response
I don't think this is possible for security reasons. The only cross domain ajax calls which browsers allow, can be done using JSONP and these are exclusively GET requests.
This will work:
$.ajax({
url: "http://somesite.com/someplace",
type: "GET",
cache: false,
dataType: "JSONP",
data: { ... },
success: function( msg ) {
alert(msg);
},
});
This won't:
$.ajax({
url: "http://somesite.com/someplace",
type: "POST",
cache: false,
dataType: "JSONP",
data: { ... },
success: function( msg ) {
alert(msg);
},
});