jQuery JSONP request causing TFL API to throw 400 - javascript

I'm using jQuery .getJSON to get data from TFL's (transport for london) API.
However adding the ?callback=? parameter to the request causes the API to throw a 400 (Bad Request) error because it is very strict about what parameters it accepts. I.E the api can't recognise '?callback' as a valid parameter and therefore freaks out.
Is there another completely different way of doing this? Somehow getting the api response and parsing it myself for example. I'm new to JS and jQuery so apologies if I'm missing something super obvious!
var busStopAPI = 'http://countdown.api.tfl.gov.uk/interfaces/ura/instant_V1?StopCode1=56094&VisitNumber=1&ReturnList=StopCode1,StopPointName,LineName,DestinationText,EstimatedTime,DirectionId';
$.getJSON(busStopAPI, this.busStopSuccess).fail(this.busStopFailure);
p.s. I've tried the other .ajax() data types but they all throw 'Access-Control-Allow-Origin' errors.

You are trying to add "callback" because you want to use JSONP, right?... and you want to do that because if you don't you get a cross-domain error, right?
I would suggest to create a local web service proxy in your server that calls TFL's api and supply data to your UI. In that way you do not have to use JSONP and do not have to worry about cross-domain issues. (more info)
FYI, there are other approaches, but I personally prefer a proxy service when the api does not support JSONP callbacks.
Hope it helps.

Related

Cross Side Scripting (JavaScript)

I am trying to Get Data from another url using JavaScript but failed , I tried All Solution from jsfiddle and Stack-overflow but one error is not going away
http://renault.twobulls.com/?code=waeuhh (Destination URL)
I tried $.getJson,$.ajax, and all even jsonp too...please help me out, I have this error when I use call back in url for jsonp
Error:
Does anyone have a solution?
You are making a JSONP request but the server is responding with JSON.
A JSONP response needs to be a JavaScript program that calls the function you specify as the callback in the URL with a single argument (which is the JSON payload).
Either change the server to make it respond with JSONP or change the JavaScript so it makes an XHR request (note that you will need to ensure the server allows a cross-origin XHR request using CORS).
Just assign it to a variable.
var someVar = {"code":"waeuhh","photoid":"1417564891877515"};

AngularJS: Unable to get responseHeaders after a $resource $save

I'm performing the following $save which calls my angularJS $resource and POSTs to my API. I'm able to debug into my success callback handler and the object is actually created in my API.
myObj.$save({}, function (value, responseHeaders) {
myObj.someSuccessFunction();
}, function (responseText) {
myObj.someFailureFunction();
});
I'm unable to retrieve anything from the "responseHeaders" param. "responseHeaders()" returns an empty object. I would like to pull the "location" response header like this: responseHeaders("Location").
It's worth noting that the Response is filled in when debugging in chrome. The "responseHeaders" object is failing to be populated for some reason.
How can we get these responseHeaders?
Thanks!
Could it be a CORS issue? If you are making the call across a domain, be sure to include cors.exposed.headers in the pre-flight OPTIONS call.
If it is a cross domain call you have to add the following header in your response headers:
Access-Control-Expose-Headers: Location
With this, the browser is capable to expose your customs headers an read it angular.
I have the same issue with spring security 4.2 CORS filter and AngularJS. My client app built using Angular JS not able to read customer authentication token from response header sent by spring rest api.
I could resolve the issue by exposing below headers.
config.addExposedHeader("Origin");
config.addExposedHeader("X-Requested-With");
config.addExposedHeader("X-AUTH-TOKEN");
config.addExposedHeader("Content-Type");
config.addExposedHeader("Accept");
config.addExposedHeader("Authorization");
config.addExposedHeader("Location");
After the above fix. My Angular code able to read headers.

Angularjs http.get failure (but I see the data was returned)

I'm walking thru the Angularjs phones tutorial and want to get the phones JSON from a remote server.
$http.get('http://myserver.com/phones.json').success(function(data) {
$scope.phones = data;
});
This failed due to CORS, I was sending an OPTIONS not a GET request, so I added this first line to the controller
delete $http.defaults.headers.common['X-Requested-With'];
I can see now in Charles that a GET not OPTIONS request is being made to myserver.com, and that the phones JSON is in the response. But the http.get is still failing with status 0 and 'data' is null.
Not sure what to try next. Any insights appreciated.
It should not be making an OPTIONS request for a GET, so that sounds right. I think what you want to do is:
$http.get('http://myserver.com/phones.json').then(function(data) {
$scope.phones = data;
}, function(err) { alert('Oh no! An error!'});
I think you want to use then(), which takes two functions as arguments — the first for success, and the second for error. $http.get() returns a promise which is acted upon by then().
Also, you probably want to use $resource instead of $http. It provides a higher level of abstraction, and allows for a more reusable style, http://docs.angularjs.org/api/ngResource.$resource
EDIT:
Check out the angular debug tool here. It shows you what is available in scopes, and shows performance data.
Well, if you are making a cross domain request, it is right to make a OPTION request as a pre-flight request to know if you are allowed to.
If the CORS fails your browser will receive the data but it'll throw an error.
So, either you put your html in the same domain or add the CORS to your backend (which is more difficult).
Here's a good tutorial which implements cross-domain GETS using the $http.jsonp method. No hacks to the headers.
http://net.tutsplus.com/tutorials/javascript-ajax/building-a-web-app-from-scratch-in-angularjs/

Is there any way to do cross-domain request from javascript and access the type of error response(401, 404, etc.) that it might generate

I tried using jquery.ajax but it fails silently whenever there is an error response
No, this is not possible without any workaround.
When making cross-domain (JSONP) requests, jQuery doesn't trigger an error event, see this answer on SO.
If it's sufficient for you to know that there was an error (without getting additional info), you could try something like this, combined with this.
If you really need the HTTP status code, you will have to work server-side, i.e. use your own server as a proxy to get the cross-domain resource. Then you can send additional info to JS using the JSONP callback; see this solution on SO.
Sorry for posting so many links, but I guess that's better than quotations... ;)

Difference jsonp and simple get request (cross domain)

I have to send (and receive) certain data to a server using JQuery and JSON.
Works so far, but not cross domain, and it has to be cross domain.
I looked how to solve this and found JSONP. As far as I see, using JSONP I have to send the callback and the data using GET (JQuery allows to use "POST" as method, but when I inspect web traffic I see it is sending actually GET and everyting as parameter).
JSONP also requires changes in the server, because they are expecting a POST request with JSON data, and they have to implement something to process the JSONP GET request.
So I'm wondering what's the difference between this and sending the data as key value parameters in GET request?
Is the difference the possibility to use a callback? Or what exactly?
Sorry a bit lost... thanks in advance
JSONP is not a form submission. It is a way of telling the server via a GET request how to generate the content for a script tag. The data returned is a payload of JavaScript (not just JSON!) with a function call to a callback which you (by convention) reference in the GET request.
JSONP works because it is a hack that doesn't use AJAX. It isn't AJAX and you should not confuse it for such because it does not use a XMLHttpRequest at any point to send the data. That is how it gets around the Same Origin Policy.
Depending on the browsers you have to support, you can implement Cross-Origin Resource Sharing headers on the server side which will let you use normal AJAX calls across trusted domains. Most browsers (IE8, Firefox 3.5+, etc.) will support CORS.
Another solution you can use if you don't want to use CORS or JSONP is to write a PHP script or Java servlet that will act as a proxy. That's as simple as opening a new connection from the script, copying all of the incoming parameters from your AJAX code onto the request and then dumping the response back at the end of your script.
I found an answer that worked for me with the cross-domain issue and JSON (not JSONP).
I simply used:
header('Access-Control-Allow-Origin: *');
inside my json file (file.php) and called it like this:
var serviceURL = 'http://your-domain.com/your/json/location.php'
$.getJSON(serviceURL,function (data) {
var entries = data;
//do your stuff here using your entries in json
});
BTW: this is a receiving process, not sending.

Categories