Strange $.post() AJAX error when parsing JSON - javascript

I am facing this strange error in using $.post.
works
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data);
$('#loader').hide();
});
});
The above piece of code, shows me the json array I am receiving using a php file, and also shows the title field here, and hides the loader image.
But when I alert(data.title), it shows me undefined. More over, when I add datatype 'json' to $.post,
doesn't work
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data);
$('#loader').hide();
}, "json"); //Added datatype here.
});
This neither alerts anything nor does it hide the loader image. I also tried,
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
jQuery.parseJSON(data);
alert(data.title);
$('#loader').hide();
});
});
The above one too neither alerts anything nor does it hide the loader. And then I tried this one too that did nothing.
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
jQuery.parseJSON(data); //tried without this too.
alert(data['title']);
$('#loader').hide();
});
});
The strangest thing is that I have previously used json as I have shown in the 2nd script(out of 4), and that works normally. My JS console too doesn't show any errors or warning. What am I doing wrong here? How do I access the title field of data?
If this helps, here is how I send the json array,
$json = array("title" => $title, "embed" => $embed, "desc" => $desc, "duration" => $duration, "date" => $date);
print_r(json_encode($json));
I would really appreciate if someone can point out the error and tell me why my scripts are failing, similar functions worked in other js file.
here is my data, that is returned by server,
{"title":"Sunn Raha Hai Na Tu Aashiqui 2 Full Song With Lyrics |
Aditya Roy Kapur, Shraddha Kapoor","embed":"\r\t\t\t\t\t\r\t\t\t\t\t</param></param>\r\t\t\t\t\t</param>\r\t\t\t\t\t\r\t\t\t\t\t</embed></object>","desc":"Presenting
full song \"Sun Raha Hai Na Tu\" with lyrics from movie \"Aashiqui 2\"
produced by T-Series Films & Vishesh Films, starring Aditya Roy Kapur,
Shraddha Kapoor in voice of Ankit Tiwari. \n\nSong: SUNN RAHA
HAI\nSinger: ANKIT TIWARI\nMusic Director: ANKIT TIWARI\nAssistant Mix
Engineer - MICHAEL EDWIN PILLAI\nMixed and Mastered by ERIC PILLAI
(FUTURE SOUND OF BOMBAY)\nLyrics:SANDEEP NATH\nMovie: AASHIQUI
2\nProducer: BHUSHAN KUMAR KRISHAN KUAMR Producer: MUKESH BHATT
\nDirector: MOHIT SURI\nMusic Label: T-SERIES\n\nBuy from iTunes -
https://itunes.apple.com/in/album/aashiqui-2-original-motion/id630590910?ls=1\n\nEnjoy
& stay connected with us!! \n\nSUBSCRIBE T-Series channel for
unlimited entertainment\nhttp://www.youtube.com/tseries\n\nCircle
us on G+ \nhttp://www.google.com/+tseriesmusic\n\nLike us on
Facebook\nhttp://www.facebook.com/tseriesmusic\n\nFollow
us\nhttp://www.twitter.com/_Tseries","duration":"391","date":"2013-04-03"}
Edit
This worked suddenly.. :o
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data.desc);
console.log(data.desc);
$("#loader").hide();
}, "json");
});

In comments, you mention that this AJAX corresponds to a YouTube API.
YouTube's blog announced in 2012 that they would support CORS, which uses server-side header flags that compatible browsers interpret as permitting requests that would otherwise be prohibited by browser security Same-Origin-Policy.
Assuming, as you say, the first example worked, the first issue was "Why did (a subsequent) alert(data.title) fail? (my edit) ". If you type alert(data.title) in the console, it will fail because the scope of data is the callback function where it is defined as a parameter, and in the global scope data is undefined. If you try to pass data back to the global scope somehow, it can still be undefined because $.post returns immediately, before the data has been fetched, and merely queues a request and sets the callback function you supply to handle the reply.
The second example, which explicitly sets the $.post dataType parameter to 'json', may fail with CORS based API because the mime types for json are not allowed to be sent up to the server as Content-Type: for a simple CORS request, and $.post will as far as I know only do simple requests without preflight. $.ajax can possibly do the more complex requests if correctly applied.
The work around to keep using $.post is not to use json as the expected data type, send requests up as form data, the server may send you back json anyway if that is what the API says will happen, which can be verified while testing the code.
From https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
Simple requests
A simple cross-site request is one that:
Only uses GET, HEAD or POST.
If POST is used to send data to the
server, the Content-Type of the data sent to the server with the HTTP
POST request is one of application/x-www-form-urlencoded,
multipart/form-data, or text/plain.
Notice that application/json did not make the list of what Content-Type is permissible in a simple CORS request.
See also A CORS POST request works from plain javascript, but why not with jQuery?

Use ajax as
$.ajax({
url:url,
type:'post',
dataType:'json',
success:callback
})
With this type you can set lots of parameter in low level.
With datatype attribute jQuery parses JSON and send data as callback function.

I think you have to replace all single \ with double '\' to feed it to JSON.parse.

Related

How to get a json response from yaler

I create an account with yaler, to comunicate with my arduino yun. It works fine, and i'm able to switch on and off my leds.
Then i created a web page, with a button that calls an ajax function with GET method to yaler (yaler web server accept REST style on the URL)
$.ajax({
url: "http://RELAY_DOMAIN.try.yaler.net/arduino/digital/13/1",
dataType: "json",
success: function(msg){
var jsonStr = msg;
},
error: function(err){
alert(err.responseText);
}
});
This code seem to work fine, infact the led switches off and on, but i expect a json response in success function (msg) like this:
{
"command":"digital",
"pin":13,
"value":1,
"action":"write"
}
But i get an error (error function). I also tried to alert the err.responseText, but it is undefined....
How could i solve the issue? Any suggestions???
Thanks in advance....
If the Web page containing the above Ajax request is served from a different origin, you'll have to work around the same origin policy of your Web browser.
There are two ways to do this (based on http://forum.arduino.cc/index.php?topic=304804):
CORS, i.e. adding the header Access-Control-Allow-Origin: * to the Yun Web service
JSONP, i.e. getting the Yun to serve an additional JS function if requested by the Ajax call with a query parameter ?callback=?
CORS can probably be configured in the OpenWRT part of the Yun, while JSONP could be added to the Brige.ino code (which you seem to be using).
I had the same problem. I used JSONP to solve it. JSONP is JSON with padding. Basically means you send the JSON data with a sort of wrapper.
Instead of just the data you have to send a Java Script function and this is allowed by the internet.
So instead of your response being :
{"command":"digital","pin":13,"value":0,"action":"write"}
It should be:
showResult({command:"analog",pin:13,value:0,action:"write"});
I changed the yunYaler.ino to do this.
So for the html :
var url = 'http://try.yaler.net/realy-domain/analog/13/210';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'showResult',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.dir(json.action);
},
error: function(e) {
console.log(e.message);
}
});
};
function showResult(show)
{
var str = "command = "+show.command;// you can do the others the same way.
alert (str);
}
My JSON is wrapped with a showResult() so its made JSONP and its the function I called in the callback.
Hope this helps. If CORS worked for you. Could you please put up how it worked here.

Cross Origin ajax "POST" request failing

I have a webservice(REST) running on localhost:8080, to call the webservice I use this jquery code:
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/user/register",
data: '{"name": "' + name + '","email": "' + email + '","password": "' + password + '"}',
beforeSend: function(x) {
if(x && x.overrideMimeType) {
x.overrideMimeType(jsonMimeType);
}
},
dataType:"jsonp",
Accept : "application/json",
contentType: "application/json",
success: registerUser_success_callback,
error: registerUser_error_callback
});
When I try to call this javascript from the same domain(i.e. localhost:8080), it work just like a charm!. Here is the screen shot of the same:
But when I try to access the same from a different domain(i.e localhost:80), it fails, and surprisingly instead of a POST, it sends out a GET and I also get a log in my server's log file, saying that the GET method not supported for REST resource. Here is the screen of the same:
From what I have read on internet(especially here, great article!), cross domain request should first send out an OPTIONS request(which is cached for later usage.) What is going wrong in my case?
I have tried calling the rest service with same parameters using FireFox's plugin RESTClient, I was able call the rest service(POST method) successfully, so this mostly is the issue with ajax part.
Help me resolve this cors hell! and do lemme know if I need to share any more details on this.
PS: After #A. Wolff Suggested, I changed the data tyoe from jsonp to json, now my browser sends out OPTIONS, but after that it doesn't send the actual POST request!!!
Well, some more digging and I found the solution to this!
After the change A. Wolff suggested, browser was sending out an OPTIONS request and was receiving a 200 response, but after that actual POST request was not being sent to the server.
Problem was, if you send any specific headers, "Content-Type" in my case, server has to add that header in "Access-Control-Allow-Headers" field of the response(response of OPTIONS request). I changed my server side code to populate that field in the response header, and VOILA!
Hope this will be helpful to others, too!
Happy Coding.

Ajax response with JSONP, can see result cannot use it

I have the following javascript:
jQuery(document).ready( function($) {
var id = "123";
var api = "example.com:8999/".concat(id)
$.ajax({
url : api,
type: 'GET',
dataType: 'jsonp',
// jsonpCallback: "localcallback",
success: function (data) { alert('success'); }
})
});
I can see the response in chrome dev tools, but the alert isn't getting called. Ultimately I need to work with this response to set the value of a div.
Image of chrome tools:
Thanks
EDIT: Put 'POST', was using 'GET', still not working. Also, I think I'd prefer "mom and pop" json, but due to CORS and the fact I'm not good with the web and am just trying to hack this together.
Your server is not returning JSONP. It's returning plain JSON. If you specify JSONP, then the server must explicitly create a JSONP formatted response or the ajax response will not be received and processed properly.
FYI, a JSONP request is sent via a script tag (that's how it gets around the same-origin limitation for cross domain requests) and the response has to be formatted as a script that calls a function and passed the requested data to that function. You can read about how JSONP works here.
Just make your ajax call without specifying the 'dataType' attribute, then control should come back to your success callback if your ajax call completes successfully.
FYI: jQuery will try to find the response data type based on the MIME type of that response.
Example:
$( function() {
$.ajax({
url :"http://example.com:8999/123",
type: 'GET',
success: function (data) {
console.log(data); // Prints the response on console
alert('success');
}
})
});
If you want to make this call only with JSONP then it would be better to share the reason with us, so that we can suggest a better solution if possible.

JQuery ajax GET request to URL fails although HTTP status is 200 OK

I apologize if this question has already been answered.
I am trying to retrieve data from a REST web service that exposes a JSON interface using jQuery .ajax call.
When I call the service using the URL, the jQuery call fails although I get a HTTP status code 200 OK.
When I copy the response into a file on the filesystem and retrieve this, the same call works.
Both the file I am accessing and the web service I am calling are on the same machine.
Some notes on the url used in the code below:
Using:
url: "http://localhost:9090/app/user/861",
the call fails, goes into .fail on all browsers.
The URL itself returns the json on all browsers:
{
"userid": 861,
"employeeno": "123",
"jobdesc": "Developer",
"firstname": "Jasper",
"lastname": "Fitussi"
}
when using "test.json" in the local filesystem following is the behavior:
url: "ajax/test.json",
On Firefox, the call executes, goes into .done and displays the result on page.
On Chrome, the call fails with status 404 and the following message -
"No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access."
I tried different combinations changing dataType:"jsonp", adding a ?callback=? to the end of the URL, and enclosing the data in the test.json with a '(' and a ')' without luck.
Please understand I am new to UI programming, javascript and jQuery.
Please help with what I am doing wrong. Here's the javascript:
<script src="http://code.jquery.com/jquery-1.10.2.js" type="text/javascript">
</script>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "GET",
url:"ajax/test.json",
// the following commented call fails, goes into .fail
// url:"http://localhost:9090/app/user/861",
contentType: "application/json",
accepts: "application/json",
dataType: "json"
})
.done(function(data) {
alert("Success");
console.log(data);
var items = [];
$.each( data, function( key, val ) {
items.push( "<li id='" + key + "'>" + val + "</li>");
});
$( "<ul/>", {
"class": "my-new-list",
html: items.join( "" )
}).appendTo( "body" );
})
.fail(function(data) {
console.log(data);
alert("Failed");
})
.always(function() {
alert("In Always");
});
});
</script>
The following is the output when I paste the url into the browser (also the contents of ajax/test.json):
{
"userid": 861,
"employeeno": "123",
"jobdesc": "Developer",
"firstname": "Jasper",
"lastname": "Fitussi"
}
Your problem is not about UI programming, it's about the security model of modern browsers :p
Access-Control-Allow-Origin errors occurs when you call a webservice (ie: load a JSON file) from a domain that is different from the one hosting your HTML page.
In your case, you are opening the html file from your hard drive (file:///) and calling a webservice on localhost.
This is a security feature in all modern browsers that forbid getting data from a foreign webservice without the webservice owners authorizing you (or everyone, wildcards are allowed) to call it.
I recommend reading the following guide from MDN, so that you understand WHY you are having this problem.
It will then be easy to resolve
https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS
If you control the source code of the webservice, or the webserver hosting it, you need to add Access-Control-Allow-Origin HTTP headers.
Do you make your ajax call using Apache on wamp, lamp, xampp or mamp or not? I think you work directly using some files lets say on your desktop and not from the www file of wamp. If the browser sends a correct url then the backend responds great, your frontend code seems fine so i think chrome complains about your not using localhost. Am i right? Whats your local development setup?
If it's a local file on the client-side, use file:/// to prefix the URL:
url: 'file:///ajax/test.json'
The third / in file:/// indicates:
As a special case, can be the string "localhost" or the empty
string; this is interpreted as `the machine from which the URL is
being interpreted'.
3.10
Reference here
Download a tool called fiddler, from http://fiddler2.com/ great way to debug web requests and to see why they are failing.
This will help you narrow down the issue you are experiencing and we can help you further because currently its all guess work.
I had the same issue, all worked fine in I.E and FireFox, a had one ajax call to a rest service using jsonp and it worked fine in chrome, however when I tried to load a file using jsonp I got the cross domain error. In short i had to add "file:" to my file path in the url
$.ajax({
type : 'GET',
url : 'file:jsondata/rain_acc_data.json',
dataType : 'jsonp',
jsonpCallback : "jsoncallback",
success : function(data) {
aler('ok');
},
error : function(jqXHR, status) {
alert("Failed to load list" + status + jqXHR);
}
});
this worked for me, make sure to wrap your json in the file with jsoncallback("your jason here");

Can not get json response using $.getJSON

I am currently developing a Ruby on rails 3 application.
My server controller function render a json object as response:
class DaysController < BaseController
...
def the_days
...
render :json => days
end
end
In my javascript,I use the following code to get json response from server( that's from the_day function in controller)
$.getJSON(
url,
{emp_id: emp_id},
function(data) {
var result = data.response;
alert(result)
alert(data)
},
"json"
);
I use firefox browswer and checked with Firebug, in Firebug Net->XHR, I see the Get request is successful, and the response "days" is there. That's both request and response are successful.
But I did not see the two alert window defined in the above $.getJSON function, why? Why I can not get the response "days" in $.getJSON function??
-----------------Edited------------------
I edited my code to this one:
$.ajax({
url: myURL,
type: 'GET',
data: {
emp_id: emp_id
},
dataType: "json",
success: function(data) {
alert("hi");
alert(data)
}
});
When I run this code, the browser is stuck at success: function(data)
If data is coming back null, but the response was otherwise successful, I'd say that you're sending the request in a manner that violates the Same Origin Policy.
The request needs to be sent to the same host/port/protocol that served the original page.
If this is only an issue in your development environment, you can test in Chrome by launching it from a Terminal application with --disable-web-security.
EDIT: Try changing the parameter name from data to something else, like dat or whatever.
Then try an alert:
alert( dat );
I've heard of some browsers having trouble with the data parameter when you utilize the data property of an AJAX call.
I'm guessing that the problem is that data does not have a response property. Try alerting just the data variable. It should be the days object itself.
I wish I could just leave a comment but I guess I don't have access to that yet.
Anyway, I'd start with something even more basic. Add some text alerts just to make sure you're actually making it to where you think you are. ie...
$.getJSON(
url,
{emp_id: emp_id},
function(data) {
alert('hi') // add this
var result = data.response;
alert('bye') // add maybe even this
alert(result)
alert(data)
},
"json"
);
Sometimes when I'm debugging I find that even my most basic assumptions are wrong.
Edit: here's some sample code from working code I recently implemented
$.ajax({
url: 'users/check_username',
type: 'GET',
data: {
username: username
},
dataType: "json",
success: function(user_exists) {
alert(user_exists) // CHANGE THIS PART
}
});
It sounds like you are not sending the correct header in your ruby application. Firebug should report the response Content Type as application/json because that is what jquery is expecting it to be.
You could try changing the datatype in your ajax call to html to see if your alerts work with that, but that doesn't really help with the json parsing.
ALL, finally, I figured out the root cause. The reason is simply because of "Invalid json data" returned in server. That's in rails controller function 'def the_days':
render :json => days
should be modified to
render :json => days.to_json
Then, everything works smoothly:) Thank you all anyhow!

Categories

Resources