Write jquery.ajax from existing javascript - javascript

I found this article:
http://msdn.microsoft.com/en-us/library/dd251073.aspx
How could I write 'get' request using jquery.ajax?

You could use the .get() method.

http://api.jquery.com/jQuery.get/
Or just use the regular $.ajax() method (http://api.jquery.com/jQuery.ajax/), which defaults to a GET request.

It depends on whether Bing's API respects the standard ?callback=function method for specifying JSONP callbacks, but if so, then this simplified version of the Search() function should do it:
// Bing API 2.0 code sample demonstrating the use of the
// Spell SourceType over the JSON Protocol.
function Search()
{
var requestStr = "http://api.bing.net/json.aspx?"
// Common request fields (required)
+ "AppId=" + AppId
+ "&Query=Mispeling words is a common ocurrence."
+ "&Sources=Spell"
// Common request fields (optional)
+ "&Version=2.0"
+ "&Market=en-us"
+ "&Options=EnableHighlighting"
$.getJSON(requestStr, SearchCompleted);
}
Keep in mind that neither approach is directly triggering a GET, like you might be used to in AJAX requests to a local server using XMLHttpRequest.
To circumvent the cross-domain restriction on XHR, JSONP works by injecting a new script element into your document which then causes the browser to load (via GET) and execute that remote script. That remote script's contents are a single function call to your callback function, with the entire JSON payload as its parameter.
If that doesn't work, including those Bing-specific callback options should work fine in conjunction with jQuery:
// Bing API 2.0 code sample demonstrating the use of the
// Spell SourceType over the JSON Protocol.
function Search()
{
var requestStr = "http://api.bing.net/json.aspx?"
// Common request fields (required)
+ "AppId=" + AppId
+ "&Query=Mispeling words is a common ocurrence."
+ "&Sources=Spell"
// Common request fields (optional)
+ "&Version=2.0"
+ "&Market=en-us"
+ "&Options=EnableHighlighting"
// JSON-specific request fields (optional)
+ "&JsonType=callback"
+ "&JsonCallback=SearchCompleted";
$.getJSON(requestStr);
}
Keep in mind that, at this point (and somewhat before), you aren't really using jQuery itself for much at all. Even though $.getJSON() or $.ajax() or $.get() seem like they're doing something more powerful than the MSDN example, jQuery is going to do exactly the same thing in this case (inject a script element with its srcpointed at requestStr).

Related

How to integrate CORS, Google Blog and JavaScript?

I have a working JavaScript on a web page that gets my blog from a blog site and displays it in a sidebar on my web page. In other words I blog in one place, but also display my blog content in another place (my web page).
The script uses Cross Origin Sharing (CORS) and looks like this:
$(
function () {
$.get(
'http://www.corsproxy.com/my_name.soup.io/rss/original',
function (data) {
var items = data.getElementsByTagName('item');
var thoughts = $('#activity ul');
var count = 0;
$(items).each(function (i, e) {
count++;
if (count > 10) return;
thoughts.append('<li>'
+ e.getElementsByTagName('description')[0].textContent
+ '<small>'
+ $.timeago( new Date(e.getElementsByTagName('pubDate')[0].textContent) )
+ '</small></li>');
});
}, 'xml'
);
}
);
I want to move my blog to Google blogging and have an account URL that looks like this: http://my_name.blogspot.com/feeds/posts/default
But I think I still need to invoke CORS so that the JavaScript on the web site can cross domains to the Google site. I have tried using the Google URL directly but the script does not get the content.
How should I change the JavaScript so that my web page running the JavaScript will display the content from the Google blog?
As an aside: using the same JavaScript, I am able to display content (the title of the commit) from my Github account on my web page. In this case I do not use CORS; the following JavaScript works as expected:
$.getScript(
'/public/bin/jquery.timeago.js',
function () {
$.getScript(
'/public/bin/jquery.github-activity.js',
function () {
$("#gh-activity ul").githubActivityFor("my_name", { limit: 10 });
}
);
}
);
Why does the Github get work without using CORS?
Can I reconfigure the get for the Google blog to act in the same way as get for my Github account?
Examining the code for the githubActivityFor call, we see:
$.get('https://api.github.com/users/' + username + '/events?callback=?', function(activity) {
...
},
"jsonp");
The "jsonp" argument tells jQuery that that JSONP is being used here, and the resource should be loaded inside of <script> tag instead of fetched with Ajax. Sure enough, we we actually look at a user's activity feed from that URL template, it's a script. jQuery can therefore perform a JSONP script load in the usual way:
storing the callback function (i.e., the second argument) in a variable with a random, long name like jQuery35758395
replacing the ? in callback=? with the same value (e.g., jQuery35758395)
loading the script resource in a <script> tag
The Github resource (like any traditional JSONP server-side endpoint) is set up to use value of the callback parameter in a function call in the beginning of the script (e.g., jQuery35758395({ 'some': 'data' }). When script runs, the function call is executed, and it triggers the randomly-named callback we set up before the fetch.
Turns out Blogger supports JSONP on their server already. If you visit http://foobar.blogspot.com/feeds/posts/default?callback=foobaz you'll see the feed data wrapped inside of a function call. To take advantage of this, simply perform your $.get with a callback=? parameter:
$.get(
'http://my_name.blogspot.com/feeds/posts/default?callback=?',
function (data) {
...
},
"jsonp");
This will automatically do JSONP behind the scenes and correctly invoke your callback function with the XML string. Unfortunately, the string won't be parsed into a DOM structure for you already, but the jQuery function (a.k.a., $) can parse the data string for you:
var feedDOM = $(data).get(1);
The get call pulls the DOM structure out of the jQuery object, but you can also keep it in the jQuery object and use jQuery functions to examine it. Alternatively, you can supply the XML string as a context argument for a jQuery selector:
var authorTags = $("author", data);

URL &callback parameter

What does the &callback parameter in a URL do? The reason I am asking is because I am running a query with jquery's $.ajax function and when I include &callback=? in the end of the url I get a 400 (bad request) error.
Here is my javascript code:
var energy_query_array = [];
var masterEnergyTable_tableid = '145TOXaanydD63tvgVMmCVH0hei0NXNCEK8ekZBg';
var current_date = 'Jan-12';
var energy_query = 'SELECT * FROM ' + masterEnergyTable_tableid;
var encoded_energy_query = encodeURIComponent(energy_query);
var energy_url = ['https://www.googleapis.com/fusiontables/v1/query'];
energy_url.push('?sql=' + encoded_energy_query);
energy_url.push('&key=' + apiKey);
//energy_url.push('&callback=?');
$.ajax({
url: energy_url.join(''),
datatype: 'jsonp',
success: function(data) {
var name_array = data['columns'];
var data_array = data['rows'][0];
for(var i = 1; i < data['columns'].length; i++) {
energy_query_array[name_array[i]] = data_array[i];
}
}
});
console.log(energy_query_array);
I have commented out the line where I add &callback=? to the url because when I leave it in the query returns the error:
"message":"Invalid value for parameter callback: ?"
However, earlier in the code I performed a similar query to google fusion tables using the same parameter for callback.
The console.log call at the end of the code displays an empty array to the console.
Callback is used for JSONP requests which is mean't to be used when doing a cross domain request to fetch JSON data. Instead of using the XHR wrapper, it uses a script tag which then passes a callback querystring parameter which points to the function that is used to execute passing in all the JSON data inside. This way you can have a datapoint which has no idea of how your application works, but when you pass in a callback then it will fire a function with the data. This allows you to use it's API from any browser.
Like any other piece of data in a query string (or anywhere else between the hostname and the fragment id), it provides some data to the server. The meaning is entirely determined by the software running on that server.
There is a convention to use callback as the key for a value that will be used as the name of the function to call in a JSON-P response in a RESTful API. JSON-P is a means to provide a web service accessible across origins for browsers which do not support CORS.
e.g.
http://example.com/foo?callback=asdf
would give you
asdf([1,2,3]);
JSON-P, obviously, requires that the server support the sending of JSON-P responses. If you try to perform a cross-origin request with jQuery it will (by default) modify the request on the assumption that the server will support JSON-P with the usual conventions.
Read about Query Strings
They start with a ?, and additional parameters get concatnated with &. The ? should never be anywhere but the beginning of the string unless it's encoded.
The key value pairs then are available to the server, as this is how a standard GET request is performed.
For example:
http://myserver.com?name=josh&age=24&state=il
Your web server is probably choking on the query string somewhere.

issue with JSONP getting a cached response from a WCF service

I use JSONP on a client to get data from a server using a WCF service that can return results using HTTP GET (It gets a 'callback' parameter which is a 'function name' and returns callback({data}), you know... JSONP).
Everything works, but if I enable caching (using 'AspNetCacheProfile')on one of the service's operations - then something is wrong, and I'm not sure what...
The way I get the JSONP is by using a function I picked up some time ago from a question here on SO (http://stackoverflow.com/questions/2499567/how-to-make-a-json-call-to-a-url)
function getJSONP(url, success) {
var ud = 'fc_' + + Math.floor(Math.random()*1000000),
script = document.createElement('script'),
head = document.getElementsByTagName('head')[0]
|| document.documentElement;
window[ud] = function(data) {
head.removeChild(script);
success && success(data);
};
script.src = url.replace('callback=?', 'callback=' + ud);
head.appendChild(script);
}
This creates a random id ('fc_xxxx') then assigns it as a function inside the window object, then use it as the 'callback' parameter for the url of the dynamic javascript that is injected to the document, and then the 'ud' function runs, removes the script and calls the 'success' callback function with the received data.
When using it on normal uncached operations from the service, it usually takes about 200ms to get back the response, and it works ok. The cached responses takes ~10ms -
and I get an error that the 'fc_XXXXX' function is undefined.
It's as if the response is "too fast" for it.
I also tried using jQuery.getJSON() - and, again the callback doesn't trigger.
In all cases when I look at the network traffic in Firebug - I can see the GET request, and I can see that the right data does in fact gets returned.
Does anybody have an idea how can I make it work right with the cached responses...?
I got it! The name of the response-function is different on each call (on both my manual jsonp implementation and that of jQuery).
The name of the function is part of the response from the server (as that's part of how jsonp works...).
So, if the response is a cached response - it will actually return the old name of the function (which will no longer exist on the client's context).
So I just need to give a constant name for the callback function in this case and it should bee fine. :)

Can I add a parameter to a PrototypeJS Ajax request using Ajax.Responder?

I'm trying to secure my AJAX calls by appending a session token (to be matched by a browser cookie by the server) as a parameter to every single AJAX request made from my web app.
I'd like to avoid having to specify the token as an additional parameter in every single Ajax.Updater() request, as that could get onerous very quickly. So I thought it might be more effective to have this token appended to every request globally, automatically.
I'm wondering whether Ajax.Responder could handle this. It seems as though it should be able to intercept any Ajax request before it's made, and modify the parameters to add the token before it's sent out. But, I have no idea how I'd go about accomplishing it. Would I need to prototype 'Ajax.Responder', and 'burn in' an additional parameter? Or is there an easier way?
My understanding of Ajax.Responder is a little weak, so if somebody could clarify why this would or wouldn't be possible in their answer, it would be greatly appreciated.
I ran into a similar problem, and ended up implementing a simple addParameters() method extension for the Ajax.Request class to get this done for both GET and POST requests.
You can check out the implementation here: https://gist.github.com/3212413.
Feedback welcome!
Prototype sets the parameters array before it calls the Responders callbacks so you can't just add the item you want to the parameters hash. You could append your variables to the url, for example this will add a cache buster random number to every request...
Ajax.Responders.register({
onCreate: function(o,x) {
o.url += (o.url.include('?') ? '&' : '?') + "rnd=" + Math.floor(Math.random()*1000000000);
}
});
this is how I implemented for a POST request, inspired by Gavin's answer:
Ajax.Responders.register({
onCreate: function(request) { // add form_key to ajax request
var formKey = $('form_key');
var parameters = request.parameters;
parameters.form_key = formKey.value;
request.options.postBody = Object.toQueryString(parameters);
}
});

Cross-domain requests with JQuery using YQL

So I need to make a a cross domain request where the response is not JSON formatted, so I cannot use .getJSON. .get obviously doesn't work because it is a cross domain request.
I came across this (Read this) when I was googling and it seems it should work for what I want to do (which is do a cross domain call that isn't json formatted using a jquery plug in). My code looks like the following. I know the url works fine because if I paste it into my browser, I can see the response, which according to last.fm documentation
The body of the server response
consists of a series of \n (ASCII 10)
terminated lines. A typical successful
server response will be something like
this:
OK
17E61E13454CDD8B68E8D7DEEEDF6170
http://post.audioscrobbler.com:80/np_1.2
http://post2.audioscrobbler.com:80/protocol_1.2
So I know my URL is fine. Now I am wondering how I get at this information, and why my version of their example does not work.
function performHandshake(sk, token, ts){
var token = md5(apiSecret + ts);
var urlToUse = "http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=tst&v=1.0&u=chamals&t=" + ts + "&a=" + token + "&api_key=" + apiKey + "&sk=" + sk + "&format=xml&callback=cbfunc";
$('#container').load(urlToUse);
$.ajax({
url: urlToUse,
type: 'GET',
success: function(res){
var headline = $(res.responseText).find('a.tst').text();
window.console.log(headline);
}
});
}
Well the page you linked you talks about using YQL and jQuery. It's a very interesting solution. However, your example seems to skip over the YQL part (which is crucial).
var urlToUse = "http://post.audioscrobbler.com/?hs=true&p=1.2.1&c=tst&v=1.0&u=chamals&t=" + ts + "&a=" + token + "&api_key=" + apiKey + "&sk=" + sk + "&format=xml&callback=cbfunc";
var yqlUrl2Use = "http://query.yahooapis.com/v1/public/yql?"+
"q=select%20*%20from%20html%20where%20url%3D%22"+
encodeURIComponent(urlToUse)+
"%22&format=xml'&callback=?"
// this function gets the data from the successful
// JSON-P call
Then you'll have to call the call the new URL as a JSONP req...
$.getJSON(yqlUrl2Use, function(json){
// figure out the format of the answer here...
});
Yeah, cross browser scripting. You can't AJAX anything like that since it violates the same domain policy.
You are going to have to setup a proxy on the same server the JavaScript is running from.
Edit Lookslike you need the $('#container').load(url) bit for that to work.
Go back an reread the linked article carefully.
You need to use $.getJSON rather than $.ajax() to return cross site information.
The var res actually has my information that I needed. I guess their headline = part was specifically for their implementation.
Thanks to those who helped!

Categories

Resources