jsonp request not working in firefox - javascript

I am trying a straightforward remote json call with jquery. I am trying to use the reddit api. http://api.reddit.com. This returns a valid json object.
If I call a local file (which is what is returned from the website saved to my local disk) things work fine.
$(document).ready(function() {
$.getJSON("js/reddit.json", function (json) {
$.each(json.data.children, function () {
title = this.data.title;
url = this.data.url;
$("#redditbox").append("<div>" + title + "<div>");
});
});
});
If I then try to convert it to a remote call:
$(document).ready(function() {
$.getJSON("http://api.reddit.com", function (json) {
$.each(json.data.children, function () {
title = this.data.title;
url = this.data.url;
$("#redditbox").append("<div>" + title + "<div>");
});
});
});
it will work fine in Safari, but not Firefox. This is expect as Firefox doesnt do remote calls due to security or something. Fine.
In the jquery docs they say to do it like this (jsonp):
$(document).ready(function() {
$.getJSON("http://api.reddit.com?jsoncallback=?", function (json) {
$.each(json.data.children, function () {
title = this.data.title;
url = this.data.url;
$("#redditbox").append("<div>" + title + "<div>");
});
});
});
however it now stops working on both safari and firefox. The request is made but what is return from the server appears to be ignored.
Is this a problem with the code I am writing or with something the server is returning? How can I diagnose this problem?
EDIT Changed the address to the real one.

JSONP is something that needs to be supported on the server. I can't find the documentation, but it appears that, if Reddit supports JSONP, it's not with the jsoncallback query variable.
What JSONP does, is wrap the JSON text with a JavaScript Function call, this allows the JSON text to be processed by any function you've already defined in your code. This function does need to be available from the Global scope, however. It appears that the JQuery getJSON method generates a function name for you, and assigns it to the jsoncallback query string variable.

The URL you are pointing to (www.redit.com...) is not returning JSON! Not sure where the JSON syndication from reddit comes but you might want to start with the example from the docs:
$(document).ready(function() {
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?", function (data) {
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#redditbox");
if ( i == 4 ) return false;
});
});
});
(apologies for formatting)
EDIT Now I re read your post, I see you intended to go to api.reddit.com unfortunately you haven't got the right parameter name for the json callback parameter. You might need to further consult the reddit documentation to see if they support JSONP and what the name of the callback param should be.

I'm not sure about reddit.com, but for sites that don't support the JSONP idiom you can still create a proxy technique (on the backend) that would return the reddit JSON, and then you would just make an ajax request to that that.
So if you called http://mydomain.com/proxy.php?url=http://api.reddit.com:
<?php
$url = $_GET["url"];
print_r(file_get_contents($url));
?>

http://api.reddit.com/ returns JSON, but doesn't appear to be JSONP-friendly. You can verify this, if you have GET, via
% GET http://api.reddit.com/?callback=foo
which dumps a stream of JSON without the JSONP wrapper.
http://code.reddit.com/browser/r2/r2/controllers/api.py (line 84) shows the code looking for 'callback' (not 'jsoncallback'). That may be a good starting point for digging through Reddit's code to see what the trick is.

Related

$.getJSON - unable to catch response when using parameters in url

I have been struggling since yesterday with the following piece of code.
function findLocation(){
alert(1);
$.getJSON( "http://www.omc4web.com/geoip/geoip.php",
{ip: "127.0.0.1",
callingurl: "www.thissite.com" },
function( result ){
alert(2);
$.each(result, function(i, field)
{
alert(i);
if(i=="country")
{
country_code = field;
}
});
})
}
It does not seem to want to get beyond the calling of the php script. The returned data is {"country":"US","store":"US"} but the function does not seem to want to process it and I never get to alert(2). I have placed monitors in the php script and I can see that it does indeed get called with the correct parameters and it does return the data expected.
if you call http://www.omc4web.com/geoip/geoip.php?ip=127.0.0.1&callingurl=www.thissite.com from your browser you will see that data is returned.
The same piece of code calling a URL with no parameters behaves correctly, but not with the above setup.
My few remaining hairs would appreciate some help on this.
additional info:
header('Content-type: application/json'); set on php script
tried it on chrome and firefox
no errors show up on firebug just a blank response screen
running script from localhost, but if its a cross domain issue, why am I able to make a similar call (without params) to amazon? $.getJSON("http://freegeoip.net/json/",function(result){ works fine as does the popular flickr example.
I am using <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Thanks in advance
Ossi
I think it's a cross domain issue. I guess you're able to use freegeoip.net because you're using JSONP. Try looking at the jQuery documentation to learn how to use JSONP: jQuery.getJSON()

$.get with dynamic data names?

I am having an issue trying to set the data name or the objects being passed in. I am writing a system that uses AJAX to send requests to the server which then returns the necessary data. However, I am trying to make things generic to where if the developer adds more "slates" then it will automatically send the request on its behalf. The code looks as following:
$(document).ready(function() {
$(".slate").each(function(){
$.get("requests.php", { $(this).attr('name') : "true" }, function(data){
});
});
});
in other words it takes the name of the element and applies it to the query string. JavaScript doesn't seem to like the
$(this).attr('name')
in the syntax which is understandable since it expects just text (not a var or a string). Is there a way to make this work? Any help is greatly appreciated!
$(document).ready(function() {
$(".slate").each(function(){
var data = {};
data[$(this).attr('name')] = "true";
$.get("requests.php", data, function(data){
});
});
});

How to read JSON data from a remote URL to a file in the local file store using JavaScript?

I want to hit a remote URL
After googling, I decided to use dojo.io.script.get, as cross-channel calls are supported only in that. But, I keep getting the below error in my FF browser, but the correct response is also shown thr.
syntax error
http://reviews.apitestcustomer.bazaarvoice.com/bvstaging/data/reviews.json?callback=%3F&Filter=ProductId%3A14151&PassKey=t5sv9b3nvawhkljtlmegk8d6s&apiversion=5.0
Line 1
?({"Includes":{},"HasErrors":false,"Offset":0,"TotalResults":2,"Locale":"en_US","Errors":[],"Results":[{"TagDimensions":{},"TagDimensionsOrder":[],"AdditionalFieldsOrder":[],"Cons":null,"IsRecommended":null,"IsRatingsOnly":false,"UserNickname":null,"Pros":null,"Photos":[],"ContextDataValues":{},"Videos":[],"ContextDataValuesOrder":[],"LastModificationTime":"2012-01-10T09:10:33.000-06:00","SubmissionId":"ex7csdrwiorg3tbgpshbfcljd","TotalFeedbackCount":0,"TotalPositiveFeedbackCount":0,"BadgesOrder":[],"UserLocation":null,"Badges":{},"AuthorId":"shiji_sk","SecondaryRatingsOrder":[],"IsFeatured":false,"ProductRecommendationIds":[],"Title":"test title","ProductId":"14151","AdditionalFields":{},"CampaignId":null,"Helpfulness":null,"TotalNegativeFeedbackCount":0,"SubmissionTime":"2012-01-09T05:55:58.000-06:00","ContentLocale":"en_US","Rating":5,"RatingRange":5,"TotalCommentCount":0,"ReviewText":"test test test test test test test test test test test test test test test test test test test test","ModerationStatus":"APPROVED","ClientResponses":[],"Id":"759582","SecondaryRatings":{},"CommentIds":[],"LastModeratedTime":"2012-01-10T09:10:33.000-06:00"},{"TagDimensions":{},"TagDimensionsOrder":[],"AdditionalFieldsOrder":[],"Cons":null,"IsRecommended":null,"IsRatingsOnly":false,"UserNickname":null,"Pros":null,"Photos":[],"ContextDataValues":{},"Videos":[],"ContextDataValuesOrder":[],"LastModificationTime":"2012-01-10T09:10:33.000-06:00","SubmissionId":"p6q13u5vgiqjfyk1xl5mktuvp","TotalFeedbackCount":0,"TotalPositiveFeedbackCount":0,"BadgesOrder":[],"UserLocation":null,"Badges":{},"AuthorId":"shiji","SecondaryRatingsOrder":[],"IsFeatured":false,"ProductRecommendationIds":[],"Title":"white review title","ProductId":"14151","AdditionalFields":{},"CampaignId":null,"Helpfulness":null,"TotalNegativeFeedbackCount":0,"SubmissionTime":"2012-01-09T04:16:40.000-06:00","ContentLocale":"en_US","Rating":5,"RatingRange":5,"TotalCommentCount":0,"ReviewText":"review for White Fabric Roll Arm Chaise & Contemporary Upholstered Armchair:\nGood one :-)","ModerationStatus":"APPROVED","ClientResponses":[],"Id":"759547","SecondaryRatings":{},"CommentIds":[],"LastModeratedTime":"2012-01-10T09:10:33.000-06:00"}],"Limit":10});
This is my script:
_invokeCrossSiteService: function(url, method, content, catEntryId, callbackFunction, appData, refresh)
{
alert("in _invokeCrossSiteService..........................");
if (content != null) {
var temp = content;
content = dojo.toJson(temp,false);
}
dojo.io.script.get({
// The URL to get JSON from Twitter
url: "http://reviews.apitestcustomer.bazaarvoice.com/bvstaging/data/reviews.json",
// The callback paramater
//callbackParamName: "callback",
// The content to send
content: {
callback: "?",
Filter: "ProductId\:"+catEntryId, // Searching for catEntryId
PassKey: "t5sv9b3nvawhkljtlmegk8d6s",
apiversion: "5.0"
},
// The success callback
load: function(resp) {
alert("resp in _invokeCrossSiteService - "+resp);
callbackFunction(status, data, appData);
},
error: function(resp){
alert("in error - "+resp);
}
});
}
Can someone pls help me out here??
Change:
callback: "?",
To
callbackParamName: "callback",
The problem is here:
callback: "?"
You're using JSON-P (not just JSON). The way JSON-P works is by adding a script element to your page with the given URL; the script is then loaded from the remote endpoint, and (by JSON-P's general contract) it consists entirely of a call to the function name you provide, passing in a JavaScript object literal (JSON is a subset of object literal syntax).
So you need to give the endpoint you're calling the name of the function it should call once the resource has been loaded, as this is how JSON-P works. So for instance:
callback: "dataReady"
...where you have this global function on the page:
function dataReady(data) {
}
Note how what you get back is in the form ?(...) — because the name you're giving the function is ?.
I expect Dojo may well have a means of handling the function name and such for you, it may be worth looking at the docs to see if there's explicit JSON-P support. (There is in some other libraries.)

How to pass variables from an HTTPObject

I'm very, very new to Javascript, and to web programming in general. I think that I'm misunderstanding something fundamental, but I've been unable to figure out what.
I have the following code:
function checkUserAuth(){
var userAuthHttpObject = new XMLHttpRequest();
var url = baseURL + "/userAuth";
userAuthHttpObject.open("POST",url,true);
userAuthHttpObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
userAuthHttpObject.onload=function(){
if (userAuthHttpObject.readyState == 4) {
var response = json.loads(userAuthHttpObject.responseText);
return response; //This is the part that doesn't work!
}
};
userAuthHttpObject.send(params);
}
I would love to call it from my page with something like:
var authResponse = checkUserAuth();
And then just do what I want with that data.
Returning a variable, however, just returns it to the userAuthObject, and not all the way back to the function that was originally called.
Is there a way to get the data out of the HttpObject, and into the page that called the function?
Working with AJAX requires wrapping your head around asynchronous behavior, which is different than other types of programming. Rather than returning values directly, you want to set up a callback function.
Create another JavaScript function which accepts the AJAX response as a parameter. This function, let's call it "takeAction(response)", should do whatever it needs to, perhaps print a failure message or set a value in a hidden field and submit a form, whatever.
then where you have "return response" put "takeAction(response)".
So now, takeAction will do whatever it was you would have done after you called "var authResponse = checkUserAuth();"
There are a couple of best practices you should start with before you continue to write the script you asked about
XMLHTTTPRequest() is not browser consistent. I would recommend you use a library such as mootools or the excellent jquery.ajax as a starting point. it easier to implement and works more consistently. http://api.jquery.com/jQuery.ajax/
content type is important. You will have have problems trying to parse json data if you used a form content type. use "application/json" if you want to use json.
true user authorization should be done on the server, never in the browser. I'm not sure how you are using this script, but I suggest you may want to reconsider.
Preliminaries out of the way, Here is one way I would get information from an ajax call into the page with jquery:
$.ajax({
//get an html chunk
url: 'ajax/test.html',
// do something with the html chunk
success: function(htmlData) {
//replace the content of <div id="auth">
$('#auth').html(htmlData);
//replace content of #auth with only the data in #message from
//the data we recieved in our ajax call
$('#auth').html( function() {
return $(htmlData).find('#message').text();
});
}
});

How to get JQuery to accept a JSON reply?

Here's some simple Javascript:
(function($){
var ajax_callback = function(data) { window.location.hash = data.h1; };
$('.clickable').live('click', function() {
$.post('server.fcgi', {}, ajax_callback, 'json');
}
);
})(jQuery);
The server is a c++ binary (yes, i know) that spits out (through fast_cgi) the string:
{"h1":"newhash"}.
The expected behavior is that the URL should change.
Instead, nothing happens and Firebug complains that 'data' is "null"!.
Any help would be greatly appreciated!
Will.
When the following code enters "ajax_callback", it says that "data" is "null"!.
But the server is a c++ binary that is confirmed to return the JSON string {"h1":"newhash"}.
Anyone have an idea why JQuery seems unable to accept the JSON data when calling the ajax_callback?
I did have similar problem as you have mentioned when using $.POST().
There are two things if you are using jquery $.post method. You need to add an extra bracket before defined data type ("JSON") as shown below. I don't know why but it works, it will return data.
$.post('server.fcgi', {}, ajax_callback,{}, 'json');
The second thing is that you will need to parse JSON data using $.parseJSON(data) in side the callback function.
One more thing to make sure that the url to fetch JSON, the page document type should be defined as JSON in the header.
I have given an example below.
$.post("url/path/here/to/json", {}, function(data){
if(data){ // just in case the called program had a problem
var obj = $.parseJSON(data);
.... do everything else using the Obj->
}
},{},"json");
This will work.
However I recommend to you to use another Jquery function specially implemented for JSON, that is called
$.getJSON();
Here is the url for more information
And I am suggesting you to use the following method instead of the one described by you.
$(document).ready(function(){
$('.clickable').live('click', function() {
$.getJSON('server.fcgi', function(data){
window.location.hash = data.h1;
});
}
);
});
Make sure the server also returns the correct HTTP headers before the payload. E.g.:
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: ...
...
{"h1":"bla"}
From your description, I could not quite make out if all it did was printf("{\"h1\":\"bla\"}"); or not.
To check the actual result, use a command line tool like HEAD, GET, wget, curl, or even nc. If you are not able to use one of those, you might get some clues from the Net panel in Firebug and the like.
Probably not the answer you want to hear, but I assume you're using jQuery 1.4.2? I noticed that this does work as expected in 1.3.2 so you might want to consider using that instead. :(

Categories