How to get json using a jsonp request - javascript

I'm trying to use instagrams api, without having to authenticate.
if I go to: https://www.instagram.com/explore/tags/chicago/?__a=1
I get a json response.
I'm trying to build an angular 4 provider that returns that data.
getInsta(term){
return this.jsonp.request(this.url+term+'/?__a=1&callback=__ng_jsonp__.__req0.finished')
.map(res => {
console.log(res.json());
});
}
I've tried "callback" and "c". I've tried JSONP_CALLBACK.
I get the error of:
"SyntaxError: Unexpected token ':'. Parse error. - In chicago:1"
and
"JSONP injected script did not invoke callback"
If I click on the unexpected token error, it brings me to the response with all the json data in it. So that means it's coming through, I just cant access it!
Any idea how i can get around this?
Here is a screenshot of the error and when clicking on the error

JSONP is a method to fetch data cross origin, it works because it injects a script tag to the body when the src of the file contains the callback function name.
<script src="http://ani.site.com/api/?callback=myGlobalFunc">
And it assumes that there is a global func on the window with the name myGlobalFunc.
The response of that call gonna look like: myGlobalFunc({data: 'data1'}).
Invocation of the function with one argument which is the data.
In your case, Instagram API return JSON not JSONP.
There for you can't use that mechanism.

Related

Getting response body for AJAX requests with SlimerJS

I'm writing a test using SlimerJS for a website and need to check the response body coming from the server. I'm using the following piece of code to get the response:
page.onResourceReceived = function (response) {
console.log(JSON.stringify(response));
};
I do receive the response but since by default to prevent too much memory usage SlimerJS keeps the response body empty I too receive an empty body, unless I tell it not to keep the body empty for certain formats using something like this:
webpage.captureContent = [ /css/, /image\/.*/ ]
I understand this works well for files with extensions like css,jpg and avi, but what about an AJAX response coming from the server. The response is in JSON format and the response body is left empty.
By looking at the response header you can tell that the response type is in text/html so by using the following code you can get the body.
page.captureContent = [/text/, /html/]

RESTful Get Request with Angular & NodeJS Express

I'm just following tutorials and figuring out how to handle get requests in NodeJS.
Here are snippets of my code:
NodeJS:
router.get('/test', function(request, response, next) {
console.log("Received Get Request");
response.jsonp({
data: 'test'
});
});
Angular:
$http.get("http://localhost:3000/test").
success(function(response) {
alert("OK");
}).
error(function(response) {
alert("FAIL");
});
If I try to access the link directly # localhost:3000/test, I'm able to receive the JSON message correctly. But when I use angularJS $http call, the request always fails and I'll find this error in the network inspector (Response)
SyntaxError:JSON.parse:unexpected end of data at line 1 column 1 of
the JSON data
The reason for that is because the response is empty but the response code is 200 in both cases.
I've tried searching for hours but maybe someone can enlighten me on this?
you could try and send
res.send('test')
and then on your http request you can use 'then'
$http.get("http://localhost:3000/test").then(function(res) {
console.log(res);
})
unlike success, then will give you a complete object (with 'test' - string as res.data)
success will bring you only the data;
then will bring you the whole object (with the status and such)..
now about that jsonp .. it's used to override a json response. you could simply use 'res.json({data: 'test'})' and it should also work for you..
hope it helps
You're using jsonp in node, which you probably don't need to. This adds extra characters to the response and so the JSON parser fails to parse (that's what the error is telling you, the JSON is malformed)
Try changing the server to look like
response.json({
data: 'test'
});
If you look in the Network pane of the developer tools, you should be able to see the raw response. It should look something like:
{"data" : "test"}

Angularjs remove line of response data before JSON eval

I am having a serious issue with Angularjs and jQuery with this particular REST API. I am not in the same domain as said API, and can get the data back, however I am getting a "SyntaxError: invalid label "name" :{" error.
If I were to do something like $http.get or $.get I get a timeout after 10 seconds. However, if I use jsonp with either library I will see in Firebug that the data is returned in the net tab, however I get the error above in the console tab. After doing some research, I have seen plenty of people having issue with the API (a Jive product) and this specific line of text that is returned along with the JSON. The response looks something like this:
throw 'allowIllegalResourceCall is false.';
{"name":{ "givenName": "xxx"}}
The big problem is the first "throw" line. I have tried a bunch of ways to remove that line but I haven't found the proper way to do it. I apologize for not being able to provide a code sample, but if there is any way to get this work in Angularjs or jQuery, I will take it. I don't know if the answer lies in Angularjs interceptors, or transformResponse.
Any help that can be provided will be appreciated.
Thank you
AngularJs allows you do define the methods for transforming the http response data (so you can remove the first line of the response data). You can do this either for a single request or add a httpInterceptor.
Single request:
$http.get('...', {
transformResponse: $http.defaults.transformResponse.unshift(function(data) {
// Remove first line of response
data.split("\n").slice(1).join("\n")
}
});
HttpInterceptor
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
'request': function(config) {
config.transformResponse.unshift(function(data) {
return data.split("\n").slice(1).join("\n")
})
return config;
}
}
})
}])
Plunker: http://plnkr.co/edit/6WCxcpmRKxIivl4yK4Fc?p=preview

Angular 1.3.0 honors JSON responses, how do I override this or pre-parse the response before Angular?

In the latest release of Angular (v1.3.0) they added a fix for the content-type header for application/json. Now all my responses get an error cause they are not valid JSON. I know I should change the back-end to respond with a plain text header, but I can't control that at the moment. Is there any way for me to pre-parse the response before Angular tries to parse it?
i think that this was the fix they made:
https://github.com/angular/angular.js/commit/7b6c1d08aceba6704a40302f373400aed9ed0e0b
The problem I have is that the response I get from the back-end has a protection prefix that doesn't match the one that Angular is checking for.
I have tried to add an http interceptor in the config, but that didn't help, still parses after Angular itself.
$httpProvider.interceptors.push('parsePrefixedJson');
The error i get in my console (it comes from the deserializing of a JSON string in Angular):
SyntaxError: Unexpected token w
at Object.parse (native)
at fromJson ...
You should use
$http.defaults.transformResponse
You also don't wanna use .push(). You need your transformer to do its thing before angular's default transformers. You should use .unshift() instead.
So your code should be
$http.defaults.transformResponse.unshift(transformResponse);
where transformResponse is a function which will transform the response from the server into a proper JSON.
I found a way to change the default transformer by adding this to the Angular app:
app.run(['$http',
function($http) {
var parseResponse = function(response) {
// parse response here
return response;
};
$http.defaults.transformResponse = [parseResponse];
}
]);
This will override the default behavior, you can also set it as an empty array if only selected responses need to be transformed.
See this question/answer: AngularJS, $http and transformResponse

How do you properly and reliably load JSON data cross-site?

I'm currently working on a userscript/extension for Chrome and am trying to pull in some JSON data from "some website". This was my approach:
$.get( "http://cloud.hartwig-at.de/~oliver/superuser.json",
function( data ) { console.log( data ); }
);
Of course, that leads to the following error:
XMLHttpRequest cannot load http://cloud.hartwig-at.de/~oliver/superuser.json. Origin http://superuser.com is not allowed by Access-Control-Allow-Origin.
I was able to resolve that after reading Origin 'url' is not allowed by Access-Control-Allow-Origin (among other questions). So, this is the next version:
$.get( "http://cloud.hartwig-at.de/~oliver/superuser.json",
function( data ) { console.log( data ); },
"jsonp"
);
Sadly, that results in another error:
Uncaught SyntaxError: Unexpected token : (superuser.json:2)
There's also a warning telling me "Resource interpreted as Script but transferred with MIME type text/plain:" which already gave me an idea what the trouble could be. (And more details were provided through Chrome says "Resource interpreted as script but transferred with MIME type text/plain.", what gives?)
Apparently, the HTTP server has to send the proper MIME type for my file, which would be application/json.
Okay, So I quickly added the required change to my mime.types and went for another go. But, no dice! The warning went away, the error didn't. I still get Uncaught SyntaxError: Unexpected token :. (I had also previously attempted to utilize the mimeType parameter to fix this, the outcome was the same.)
The MIME type looks fine though:
Now I'm somewhat out of ideas. The content of the .json file validates fine on http://www.jslint.com/
Telling the jQuery's get to do JSONP does not magically make it work. It makes a JSONP request, but the server on the other end needs to support JSONP calls.
The response from the server should look something like
someFunction( { "foo" : "bar" } );
See jQuery's docs on getJSON with JSONP to see how to use the callback
If it is a modern day browser you can use CORS and you have control over the second domain.
Other option is a serverside proxy on your domain that requests data from the other domain. Or you can use a service like Yahoo pipes.
You can't use JSONP on a request unless the server supports it. The way JSONP calls work is that you pass a callback=something parameter along with the request and the server encapsulates the JSON with something() so that it can be loaded by your browser by calling something when the script is accessed.
Another way to get it to work is to configure that server to set the CORS headers correctly, if you own the domain.
If you don't have access to the server, consider using a JSONP proxy, which wraps the first step for you. I've used YQL to do this (see the link), which doesn't require me to set anything up myself. Below is coffeescript code that does that:
uri = "http://cloud.hartwig-at.de/~oliver/superuser.json"
jqxhr = $.getJSON \
"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" \
+ encodeURIComponent(uri) + "%22&format=json&callback=?"
jqxhr.success (yql) ->
unless yql.query.results
alert("Failed to get stuff")
return
json = $.parseJSON(yql.query.results.body.p)
# do stuff with json
And in the form of javascript using http://js2coffee.org:
uri = "http://cloud.hartwig-at.de/~oliver/superuser.json";
jqxhr = $.getJSON("http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22"
+ encodeURIComponent(uri) + "%22&format=json&callback=?");
jqxhr.success(function(yql) {
var json;
if (!yql.query.results) {
alert("Failed to get stuff");
return;
}
json = $.parseJSON(yql.query.results.body.p);
// do stuff with json
});

Categories