in my code i have:
$.ajax({
url: 'http://chapters.zmgc.net',
dataType: 'jsonp',
success: function(d){ // "Type","Name","Link","Contact","Location","Icon"
Tabzilla.zgContacts = d;
var countries = [];
d.rows.forEach(function(row){
if (row[0] == 'Country') countries.push(
{link:row[2], contact:row[3], country: row[4]}
);
});
but i get an error, Uncaught SyntaxError: Unexpected token :
{
"kind": "fusiontables#sqlresponse",
....
if i replace the url with the actual file and remove the dataType, all works as expected!
i have validated the output of http://chapters.zmgc.net at http://jsonlint.com/ and it is ok.
looking at the response headers returned from http://chapters.zmgc.net, it is:
Connection:keep-alive
Content-Type:application/json
Date:Thu, 13 Dec 2012 17:02:27 GMT
Transfer-Encoding:chunked
here is the code https://github.com/tomarcafe/Z-Tabzilla/blob/gh-pages/z-tabzilla.js#L282 i would like to replace the local file with reading the remote data?
what am i missing?
You shouldn't set type to jsonp, That is JSON with padding, in that it is assumed that response is wrapped inside a function call.
callback({payload: values});
and will tried to be executed.
Instead use type: json, or simply $.getJSON which will correctly pass the JSON payload with $.parseJSON.
It's because you're asking for JSONP (JSON with padding) and getting JSON without padding. JSONP is JSON that is padded by a function call, and the only way to get it to work is by adding support for JSONP on the server.
If you don't have access to chapters.zmgc.net you'll have to contact them and ask them to add support for JSONP.
If you do have access you can add ?callback=parseThis to your url and then read that variable on server-side and pad your JSON accordingly:
parseThis(/* put your json in here */);
However, if you don't define your own callback, jQuery will add one automatically that you can use. They will look something like this: jQuery18200710562220774591_1355419375476
As Ajax uses jsonp (json with padding) but your url doesn't seem to be jsonp compatible, so you have to avoid using that.
from jQuery:
"jsonp": Loads in a JSON block using JSONP. Adds an extra
"?callback=?" to the end of your URL to specify the callback. Disables
caching by appending a query string parameter, "_=[TIMESTAMP]", to the
URL unless the cache option is set to true.
more here : http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/
Related
If I run a get request like this:
$.ajax({
url: 'http://localhost:8000/api/points/',
contentType:"application/json",
dataType: "json",
data: JSON.stringify({"content_type":content_type,"object_id":object_id}),
type: 'GET',
}).error(function(r){ $(output).text('error') })
.success(function(r){
$(output).text(r.count);
})
Its request goes to:
http://localhost:8000/api/points/?{%22content_type%22:8,%22object_id%22:40}
Obviously that's bad. It works okay if I don't do JSON.stringify(), but why is that?
Curiously if I do a POST request it's the opposite! I have to stringify the data or it won't work. So why the difference?
First of all let's fix your request:
var req = $.ajax({
method: "GET",
url: "http://localhost:8000/api/points/",
dataType: "json", // is you telling jQuery what kind of response to expect.
data : {id : '12345'}
});
req.done(function(data){
// do something with the data
});
req.fail(function(jqXHR, status, err){
// do something in case of failure
throw err;
});
Next get to know what you are dealing with :
data : PlainObject or String or Array
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded".
Note: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks will be deprecated in jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
At last:
No need for : JSON.stringify({"content_type":content_type,"object_id":object_id}) as it is a wrong way to do it with JSON.stringify just :
{ 'content_type' : 'type', 'object_id' : 'id' }
Urahara's answer contains some useful suggestions, but does not seem to address your question.
Well, it seems that your server side code is expecting to find a json object in the body of the POST request. Why would that be? Because you specify that the content type be "application/json". So in the case of a PUT case, when you use JSON.stringify your data in the $.ajax call is a string that happens to represent a JSON object. This is passed as is and so this works. You end up sending something like
{"content_type":8, "object_id":40}
as the body of your POST request and your server side code is happy to process this. Not sure exactly what your server-side technology is, but presumably it also binds content_type to 8 and object_id to 40, which makes you happy :-)
But when you do not use JSON.stringify to turn the object into a JSON string, you end up passing the object itself to $.ajax having it turn it into a string in the way it knows how. Well, it only knows only one: the good old url-encoding way. So the server, would still be expecting a JSON object but would instead be getting
content_type=8&object_id=40
as the body of the PUT request. It will not be happy. This is not a JSON object like your content-type promised! :-)
Now, moving on to the case of a GET request. Here the content-type is pretty much irrelevant as the message body will be empty. If you use JSON.stringify what you pass as the request data is a weird JSON-object representing string and the monstrosity that you get as a URL
http://localhost:8000/api/points/?{%22content_type%22:8,%22object_id%22:40}
is as you 'd expect not very well received by the server. What the server is happy with is something like
http://localhost:8000/api/points/?content_type=8&object_id=40
Which is exactly what $.ajax produces when you do not use JSON.stringify but rather pass it a nice pair of attribute-value pairs. It just url-encodes them, exactly like it did in the PUT case, and the server is happy.
So $.ajax always url-encodes objects consisting of attribute-value pairs. This is fine in most cases. One way to fix your code to do a POST without using JSON.stringify would be to simply not put a content type parameter in the $.ajax call (in which case the default, 'application/x-www-form-urlencoded; charset=UTF-8' will be used).
But if you want to pass more complex, deeply hierarchical objects, using some object serialisation format you have to set the appropriate content type and pass the data as a string using the corresponding encoding (JSON, XML, etc.) like you did here.
Hope that answers your question :-)
Please also have a look at http://api.jquery.com/jquery.ajax/
I am parsing generated json with jquery $.ajax but there is one option that I dont understand. I saw it in some examples and tried to look for at jquery.com but still not sure about it:
this option is:
data: { get_param: 'value' }
which is used like this:
$.ajax({
type: 'GET',
url: 'http://example/functions.php',
data: { get_param: 'value' }, //why we shell use that in that case?
success: function (data) {
var names = data
$('#cand').html(data);
}
});
I know that "data:" is what sent to the server but parsing JSON I thought i don't send but retrieve from server with GET type. And the next part "get_param: 'value'"
does not make sense to me in that case either, could anyone please explain when and what for and in what cases it shell be used?
thank you.
I know that "data" is what sent to the server
Yes. If data is an object, it gets serialized to an application/x-www-form-urlencoded string and then placed in the query string or request body as appropriate for the request type (GET/POST).
jQuery does all the escaping necessary for this.
(It also, by default, collapses nested data structures (you don't have any in your example) into PHP-style by adding [] to key names).
but parsing JSON
JSON is not involved (unless the server responds with some).
when and what for and in what cases it shell be used
Whenever you want to pass data to the server rather than requesting a static URI.
You don't send JSON (usually), you send simple GET or POST HTTP parameters. They are given to the ajax method in an object literal usually, but you could have used the string "getparam=value", too. If you provide an object, jQuery will do the parameter-serialisation and URL-encoding for you - they're sent as x-www-form-urlencoded.
To cite from the docs:
data (Object, String)
Data to be sent to the server. It is converted to a query string, if
not already a string. It's appended to the url for GET-requests. See
processData option to prevent this automatic processing. Object must
be Key/Value pairs. If value is an Array, jQuery serializes multiple
values with same key based on the value of the traditional setting.
i'm doing an ajax request with query and wondering why my response is already a JS object.
If i do a
var obj = jQuery.parseJSON(response);
'obj' is null, but i can use 'response' as an array of js objects.
This is not really a problem, but i would like to understand this behavior.
Thanks
This happens when you make an AJAX call and specify the dataType JSON jQuery calls jQuery.parseJSON on the response for you. In fact you can specify what function to call depending on the dataType as you can se from the documentation
converters(added 1.5)
Map Default: {"* text": window.String, "text
html": true, "text json": jQuery.parseJSON, "text xml":
jQuery.parseXML} A map of dataType-to-dataType converters. Each
converter's value is a function that returns the transformed value of
the response
So if you make a call like this
$.ajax({
url: yoururl,
dataType: "json",
success: function(data){
//data is already a json
}
If you don't specify a dataType jQuery tries to guess it
dataTypeString Default: Intelligent Guess (xml, json, script, or
html)
The type of data that you're expecting back from the server. If none
is specified, jQuery will try to infer it based on the MIME type of
the response (an XML MIME type will yield XML, in 1.4 JSON will yield
a JavaScript object, in 1.4 script will execute the script, and
anything else will be returned as a string). The available types (and
the result passed as the first argument to your success callback) are:
"xml": Returns a XML document that can be processed via jQuery.
"html": Returns HTML as plain text; included script tags are evaluated
when inserted in the DOM. "script": Evaluates the response as
JavaScript and returns it as plain text. Disables caching by appending
a query string parameter, "=[TIMESTAMP]", to the URL unless the cache
option is set to true. Note: This will turn POSTs into GETs for
remote-domain requests. "json": Evaluates the response as JSON and
returns a JavaScript object. In jQuery 1.4 the JSON data is parsed in
a strict manner; any malformed JSON is rejected and a parse error is
thrown. (See json.org for more information on proper JSON formatting.)
"jsonp": Loads in a JSON block using JSONP. Adds an extra
"?callback=?" to the end of your URL to specify the callback. Disables
caching by appending a query string parameter, "=[TIMESTAMP]", to the
URL unless the cache option is set to true.
"text": A plain text
string. multiple, space-separated values:
As of jQuery 1.5, jQuery can
convert a dataType from what it received in the Content-Type header to
what you require. For example, if you want a text response to be
treated as XML, use "text xml" for the dataType. You can also make a
JSONP request, have it received as text, and interpreted by jQuery as
XML: "jsonp text xml." Similarly, a shorthand string such as "jsonp
xml" will first attempt to convert from jsonp to xml, and, failing
that, convert from jsonp to text, and then from text to xml.
It pretty much depends which dataType you pass into your jQuery ajax request. This might happen implict by calling .getJSON() or directly using $.ajax().
However, if you omit the dataType, jQuery trys to do some magic and guesses which data was received. As for JSON data, it uses a simple regular expression to check if a response looks like a JSON-string and if so, it automatically parses it for you.
jQuery will try to infer it based on the MIME type of the response.
So always be precise and tell jQuery which type of data you expect.
The default behaviour of jQuery's ajax method is to analyse the response and return it as the most appropriate data type. If your response looks like JSON, therefore, it will be converted to a JavaScript object/array.
You can override this behaviour by setting the dataType attribute in the ajax settings.
if you specify the dataType as json the jquery parses the response for you like
$.ajax({
...
dataType:'json',
...
});
same is the case with jQuery.getJSON()
this is how the source code for getJSON looks like
getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );
},
https://github.com/jquery/jquery/blob/master/src/ajax.js#L283
Because
jQuery.ajaxSettings.converters["text json"] === jQuery.parseJSON
I.E it will run the function everytime json response is detected automatically or explicitly set by yourself
I have links like
http://example.com?query1=query1&query2=query2 as href of anchor tag.
I want to do post ajax on href click using data from the query parameter from the link.
I have written code
$("a").bind('click',function(){
$.ajax({type:'post',url:$(this).attr('href'), success: function(data){
alert(data);
}})
return false;
});
but it does not send query parameter inside ajax post request. Request query data length is 0.
how can I change this code to manipulate data from query parameter of link ?
Edit
Sorry my bad but it is not working these are the request
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:0
Query String parameter
action:delete
id:12
So these fields are not going inside request content.
You need to use the value of the href attribute, not just the jQuery object itself.
url:$(this).attr('href').val()
Update
Although you said this answer worked for you, I made a mistake. val is not a valid function of attr however doing it the original way you had it works for me.
See this demo: http://jsfiddle.net/PuyzU/
Update 2
Ok, I see your problem now. It wasn't atall clear from the question what you meant.
Let me rewrite your question here to make sure I'm on the right track.
I want to take the querstring parameters of a URL and use them in my ajax
POST action. How do I do that with jQuery?
In your ajax post method there is a property data where you'll store the data you want to post to the server.
$.ajax({
type: 'post',
url: "http://[...],
data: DataToPostToServerHere
[...]
In this case we can obtain the querysting parameter values as a single string by splitting our URL on the ? and use the first portion of the array as the URL and the second portion as the data we're sending:
var urlFull = $('#myLink').attr('href').split('?');
urlFull[0] // Our URL
urlFull[1] // The data to put into the data property for posting.
Working Example
Why does this not work? anybody:
In my code I have:
$.getJSON("http://isp123.co.uk/cw/NorthWales/Test.txt?jsoncallback=?",
function(data){
//This never gets executed
alert('here');
});
The text file can be viewed here:
http://isp123.co.uk/cw/NorthWales/Test.txt
This is not a JSONP response:
({"name" : "hello world"});
If you had a proper JSONP response, then your code should work.
The question mark in the "callback=?" part of the URL is changed by jQuery before making the request, your JSONP server needs to be able to dynamically create the JSONP "function" in response to the unique jQuery request. If you can't dynamically create your JSONP, perhaps you could use YQL/Yahoo pipes to turn it into JSONP?
This pipe should do the trick, to see if it works, use this URL instead in your getJSON function: http://pipes.yahoo.com/pipes/pipe.run?u=http%3A%2F%2Fisp123.co.uk%2Fcw%2FNorthWales%2FTest.txt&_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&_callback=?
I just tried this and it worked:
$.getJSON("http://pipes.yahoo.com/pipes/pipe.run?u=http%3A%2F%2Fisp123.co.uk%2Fcw%2FNorthWales%2FTest.txt&_id=332d9216d8910ba39e6c2577fd321a6a&_render=json&_callback=?", function(data){
//This always gets executed!!!
alert('here');
});
I don't know if you know enough about JSONP but this is not JSONP
?({"name" : "hello world"});
It really should be something like this http://isp123.co.uk/cw/NorthWales/Test.txt?jsoncallback=foo
foo({"name" : "hello world"});
From the jQuery.getJson manual page:
Important: As of jQuery 1.4, if the JSON file contains a syntax error, the request will usually fail silently. Avoid frequent hand-editing of JSON data for this reason. JSON is a data-interchange format with syntax rules that are stricter than those of JavaScript's object literal notation. For example, all strings represented in JSON, whether they are properties or values, must be enclosed in double-quotes. For details on the JSON format, see http://json.org/.
Your JSON is invalid according to http://jsonlint.com/
Here Clearly mentioned
As of jQuery 1.5, setting the jsonp
option to false prevents jQuery from
adding the "?callback" string to the
URL or attempting to use "=?" for
transformation. In this case, you
should also explicitly set the
jsonpCallback setting
and read jsonpCallback section
jsonpCallback,
Specify the callback function name for
a JSONP request. This value will be
used instead of the random name
automatically generated by jQuery. It
is preferable to let jQuery generate a
unique name as it'll make it easier to
manage the requests and provide
callbacks and error handling. You may
want to specify the callback when you
want to enable better browser caching
of GET requests. As of jQuery 1.5, you
can also use a function for this
setting, in which case the value of
jsonpCallback is set to the return
value of that function
Probably worth using jQuery.ajax() - http://api.jquery.com/jQuery.ajax/
You can pass in the dataType as "jsonp" and then jQuery takes care of all the callback business, but more importantly you can specify a function to run when there's an error, which may help you:
$.ajax({
dataType: "jsonp",
success: function(d) {console.log(d);},
error: function() { console.log("error") } //do your debugging in here
//add other parameters such as URL, etc
});
The error function you define can be passed 3 variables, read up on it on the ajax() page on the jQuery docs (linked at the beginning of my post) to find out more about that and how to use them.
Your problem lies with how your server is outputting the information. In the link you've supplied, the assumption is that any name placed in the ?jsonpcallback should result in wrapping the JSONP code in a function with that same name. It, however, is not the case.
So the next option is this: use a static function name in your server file and wrap the code. (e.g. use foo(<jsonp>) and stick with it) Then, you have to explicitly tell jQuery that we are going to use a specific function name (leave jQuery with the assumption it's supplying (and thus receiving) that name back, when in-fact you're just supplying it server side and filling in the blanks).
Once you have your file setup, use something like the following:
$.ajax({
// setup the request
url: 'http://isp123.co.uk/cw/NorthWales/Test.txt',
crossDomain: true,
dataType: 'jsonp',
jsonp: false,
jsonpCallback: 'foo', // "supply" the jsonp function (pseudo-defined)
// function to call when completed
complete: function(data){
alert(data);
}
// just in case, catch the error
error: function(j,t,e){
alert('AJAX Error');
}
});
So now when jQuery makes the call and it thinks it's supplying the callback, it's really just getting the server-defined callback in return. So, for the above to work, your text file should look something like this:
foo({name:"Hello, World!"});
Also, if you can, change your header to application/javascript, though this is some-what optional.