success callback never get invoked for a JSONP request - javascript

I have this URL: https://cdn.static.wizzair.com/en-GB/TimeTableAjax?departureIATA=BUD&arrivalIATA=TLV&year=2016&month=6
which returns me a json. if I go to this URL with my browser or if I'm firing the request using a REST client on my browser (DHC) it works! Now, for me with an express server that runs over https, I'm trying to make this request works using jQuery with no luck.
Somehow the error callback is always being executed even though I see in the network debugging that the request was good and seeing the json response!
My code:
/// removed old code ///
$.ajax({
method: 'GET',
url: "https://cdn.static.wizzair.com/en-GB/TimeTableAjax?departureIATA=BUD&arrivalIATA=TLV&year=2016&month=6&callback=?",
dataType: "jsonp",
success: function() { console.log("success"); },
error: function(err) { ;console.log(err); }
});
** * EDIT * **
so I understand this will not work as the target does not support jsonp.
changing it to normal GET request will gets an error and this message:
XMLHttpRequest cannot load https://cdn.static.wizzair.com/en-GB/TimeTableAjax?departureIATA=BUD&arrivalIATA=TLV&year=2016&month=6. The 'Access-Control-Allow-Origin' header has a value 'https://wizzair.com' that is not equal to the supplied origin. Origin 'https://localhost:3000' is therefore not allowed access.
which is expected. But how come this works on my browser and with the locally rest client? What am I doing wrong?
Thanks!

The URL you are requesting is returning JSON, not JSONP.
JSONP requests only work if the server is designed to respond to them with a JSONP formatted response.
For further reading, see What is JSONP all about
Regarding the significant edit to the question: See this duplicate.

Related

Cross-domain GET request, difference between browser and localhost making the call

I attempt to make a GET request to an API from a locally hosted meteor app (=> App running at: http://localhost:3000/) and upon doing so I get the error:
"XMLHttpRequest cannot load [the-api-url]. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:3000 is therefore not allowed access."
Yet when I paste [the-api-url] into my browser and hit ENTER, the appropriate API response is shown in my browser window (a little JSON object). I have read some other SO posts about cross-domain request issues, but I don't understand the solutions, or what the difference is between sending the GET from my code or from the browser. Can someone explain why this behavior occurs, and what the appropriate change to my code/design is? My existing code is as below:
$.ajax({
type: "get",
url: auth_ad_act_url,
data: {
ads_token: ACCESS_TOKEN
},
dataType: 'jsonp',
success: function(data, status) {
console.log(data);
}
});
EDIT:
I do a jQuery.ajax() of type "get" supplied with a URL, parameters object, and success callback function, and dataType 'jsonp' to deal with cross-domain requesting.
I posted new code. Now the error is that the response is not correct. (I know this because it worked from my browser, and that responsee lined up with the API documentation). The response is "Resource interpreted as Script but transferred with MIME type text/html: https://host.com/apps/[my-app-id]/authorize_ad_account?callbac…" but it should be an object with the key 'url' and one other thing. I also get the error "Uncaught SyntaxError: Unexpected token :" when I include 'jsonp'. But that incorrect response mentioned above still gets logged to console so I don't understand when that syntax error happens, or where.
The Same Origin Policy does not include what you type into your address bar. If it did, you literally would not be able to access any website at all unless it was saved on your local machine!
In your situation, in order to get the resource that you need from jQuery's get, you'll either need to use a server-side proxy hosted on a matching domain, or since you're consuming JSON see if the API you're using supports JSONP.
There is a possibility to get JSON Data with a cross-domain request. You have to use JSONP and define a callback method, which has to be in the call and in the JSON Data.
Your request:
$.ajax({
type: "GET",
url: auth_ad_act_url + "&callback=?",
jsonpCallback: "jsonCallback",
dataType: "jsonp",
success: function(data) {
// Do something with the data
}
)};
The JSON File on the external server:
jsonCallback(INSERT_HERE_THE_JSON_DATA);
If you do not have the possibility to add the jsonCallback on the external server, check out CORS.

JSON Get request using JQuery (cross-domain)

I'm trying to make a simple JSON get request to an API on a domain that I do not control.
My code is simply:
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'http://pubapi.cryptsy.com/api.php?method=marketdatav2',
success: function (data) {
console.log(data);
}
});
});
But since that is a cross-domain request, I am getting this error in the Chrome Console:
XMLHttpRequest cannot load http://pubapi.cryptsy.com/api.php?method=marketdatav2. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
And when I try to add the parameter dataType: 'jsonp' the Console returns with this error:
Uncaught SyntaxError: Unexpected token :
But when I examine the Network tab in Chrome I see that under Headers the Status Code is 200 OK and I can actually see the full response in the Response tab, but the console is still showing the "Unexpected Token :" error and the JQuery JSON request is still failing.
Here's the JS Fiddle link: http://jsfiddle.net/6Qcq2/ You can see the same results
I have tried running the url on http://www.hurl.it and it shows me Status OK and the response as well, so I must be doing something wrong.
I've pretty much wasted the whole day trying to figure out how to get around this problem.
Your help is very much appreciated.
The response from the API is JSON, not JSONP, so just changing the data type doesn't help.
You can use a proxy that makes the request and turns the JSON into JSONP:
$(document).ready(function () {
$.ajax({
type: 'GET',
url: 'http://jsonp.guffa.com/Proxy.ashx?url=pubapi.cryptsy.com%2fapi.php%3fmethod=marketdatav2',
dataType: 'jsonp',
success: function (data) {
console.log(data);
}
});
});
Demo: http://jsfiddle.net/6Qcq2/1/
You need to setup some type of proxy script. Due to the Same-origin policy, you can't make an ajax call to a resource that is on an external domain. You can get around this by setting up a simple PHP script that will query the data for you. Then, you would point your ajax call to your script (which will be hosted on your domain). The content type for that resource is application/json, so telling jQuery the type is jsonp won't help you.
AJAX requests do not work cross-domain for security reasons. Since you're reading JSON data, you may be able to make JSONP work.
Shouldn't the jsonp response direct to a callback?
What is JSONP all about?

Jquery Ajax Request Called Twice and the first request does not send token in header

I am using ajax to call a WCF REST based service.
The ajax method is called before the page gets loaded.
I wish to send a "Token" in the header of ajax request. In fiddler this is what I see:
1.)A request to the service without the token in the header.(AJAX Call failure)
2.)A request to the same service with the token in the header.(AJAX Call Passed)
After that everything works fine on chrome and safari. But there is only one service call on IE 10 and Mozilla. As a result the service call fails in IE 10 and Mozilla since there is no token in the header of the request.
This is the method that I call:
function callservice (method, serviceUrl, params, successHandler, errorHandler) {
$.ajax({
crossDomain: true,
type: method,
url: serviceUrl,
beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Authorization", Token); },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successHandler,
error: errorHandler
});
function photos(data) {
alert(data);
console.log(data);
};
}
I control both the Web Service and the application(Which calls this Web Service). This problem does not arise when both the application and web service are hosted on the local host.In that case there is only one successful service call. But there are two AJAX calls when there is a cross domain call.
My question is why doesn't the AJAX request send the token in the first attempt?
And why does the token get sent only in the second AJAX call?
Any kind of help will be greatly appreciated.
The problem was with CORS.Earlier,browsers did not allow ajax requests to be made to a domain which is different than that of a client as it was considered as a security threat.Modern browser's can make cross domain ajax request's as long as the server co-operates with the client.So this is what actually happens when there is a cross domain request from a browser:
1.)First the browser sends 'Preflight' request to the service to gather authorization information(which was a request with the header method as 'OPTIONS' in my case) from the WCF service. In return the Web Service sends Access Control Allow Origin as a part of its response header.And the error being displayed on fiddler as a result of this request was a HTTP 500 error.This AJAX request has nothing in the data field since it was just a way to find the authorization details of the WCF service.
2.)Chrome and Safari then made a second request to the Web Service now that they have the authorization details of the service.Whereas Firefox and IE did not prefer to make a second ajax request to the service since there was an HTTP 500 error for the pre-flight request. Hence both Chrome and Safari were able to communicate with the service.
So the solution was to modify the response from the WCF service in case there is a 'Preflight request' made to it.I modified the response sent by the service in case there is a 'Preflight request' to send an HTTP 200 OK Response. This allowed browsers like IE and Mozilla to send the actual request after the preflight request.
Here is one of the sources which I referred:
http://www.bennadel.com/blog/2327-Cross-Origin-Resource-Sharing-CORS-AJAX-Requests-Between-jQuery-And-Node-js.htm
Hope this helps people facing the same problem.
Cross domain call is under the same origin policy. You can not make the calls by default. You need to use CORS or JSONP or a proxy.
XMLHttpRequest: Unless they changed it, With MS Explorer you'll need to use ActiveXObject("Microsoft.XMLHTTP"). For my ajax call made in plain JS, i use this line to create the object according tyo the browser:
if (window.XMLHttpRequest){
//for most BRowsers
r = new XMLHttpRequest();
} else{
//for Explorer
r = new ActiveXObject("Microsoft.XMLHTTP");
}
then apply your beforesend to the object created here (r) in my case. I truely believe this is your issue with EI. But not tested.

Trouble performing simple GET request returning JSON with Javascript

I'm horrible at Javascript, so sorry in advance for what I'm going to go ahead and assume is an amazingly stupid question.
I'm simply trying to perform a GET request to GitHub's public repo API for a given user, and return the value as JSON.
Here's the function I'm trying to use:
function get_github_public_repos(username) {
var the_url = "http://github.com/api/v2/json/repos/show/" + username
$.ajax({
url: the_url,
dataType: 'json',
type: 'get',
success: function(data) {
alert('raw data: ' + data)
var json_response = $.parseJSON(data);
alert(json_response);
}
});
}
This is returning Null for data. And in the console, I see Failed to load resource: cancelled. I know the URL is correct, because if I run curl on the url, it returns the expected data.
jQuery's ajax function supports JSONP which allows cross-domain requests (which you need because you're trying to request data from github.com from another domain). Just change the dataType from 'json' to 'jsonp';
function get_github_public_repos(username) {
var the_url = "http://github.com/api/v2/json/repos/show/" + username
$.ajax({
url: the_url,
dataType: 'jsonp',
type: 'get',
success: function(data) {
var json_response = data;
alert(data);
}
});
}
UPDATE: It's import to note that the end pint (in this case github.com's API) has to support JSONP for this to work. It's not a guarnateed solution for ANY cross-domain request as pointed out in the comments.
JavaScript is subject to cross-domain restrictions when making requests on a different server.
Well, unless you run your code in the github.com domain, that won't work.
You can use simle ajax only in your domain.
One solution is to create a proxy for it. Make a page on your server that does one thing, gets your requested (out of domain) content with curl, and prints it. Then you call this proxy with ajax.
The XmlHttpRequest object (which $ajax uses) cannot download content from a different domain due to the same origin policy. You would need to use something such as JSONP to be able to do this from a browser.
As the others have said, you cannot execute ajax on a remote domain.
You will need to write a server sided script on your domain (such as php), that will do the dirty work retrieving the information needed from the github domain.
Then, use your ajax to query your server side script for the information.
I know the URL is correct, because if
I run curl on the url, it returns the
expected data.
Use that idea to get your ajax working. Create a proxy page on your site that uses curl to retrieve the data you want, then have your "the_url" variable point to that page on your site. Cross-domain restrictions prevent you from being able to use ajax in the manner you attempted.

Basic Authentication with jQuery.ajax request and jsonp

I have some local html/js files with which I'd like to invoke some remote servers via https and eventually use Basic Authentication for the request.
I am encountering two problems. First is that if I don't specify 'jsonp' for the dataType, jQuery.ajax() request returns the error:
Access to restricted URI denied code:
1012
Are my requests considered cross-domain because my main work file is stored locally, but retrieving data from a server elsewhere?
So fine, I update the call so it now looks like:
$.ajax({
url: myServerUrl,
type: "GET",
dataType: "jsonp", // considered a cross domain Ajax request if not specified
username: myUsername,
password: myPassword,
success: function(result)
{
// success handling
},
error: function(req, status, errThrown){
// error handling
}
})
Because I need to use Basic Authentication, I'm passing in the username/password but if I monitor the request, I don't see it being set and additionally, the server sends an error response since it doesn't have the expected info.
Additionally, because I have jsonp set, beforeSend won't get invoked.
How do I pass along the credentials using Basic Authentication for this request?
The short version is you can't do this. Your suspicions are correct, because you're local and these files are remote, you can't access them, you're being blocked by the same-origin policy. The work-around for that is JSONP, but that really doesn't seem to apply to your situation...
JSONP works differently, it's a GET request via a <script> tag include to get the file, so you're not sending special headers or anything.
You'll need to proxy the request through the server you're on (the domain of where this script is running) or another proxy option, but going from the client to another domain is blocked, mainly for security reasons.
Try doing http://user:password#restservice. This mimics a basic-auth request.
I think you'll have to add a server proxy of some sort. JSONP is just a particular way to use a script tag. Thus, it doesn't allow setting arbitrary headers. And of course, you can't do a cross-origin XHR.

Categories

Resources