How to perform cross-site ajax request? - ajax

Browsers don't allow cross-site AJAX calls (it's a security restriction).
Is there any possible solution ?
EDIT
I control only the caller website

If you control both parties then there a lot of options. Such as JSONP, or modifying header responses of the remote website. Unfortunately, JSONP only works if the remote website supports it. You can't force a JSONP call to a website that doesn't already support it.
However, as you have said, you only control the source website. You cannot hack the browser around this restriction for obvious reasons. You do have a third option which is creating a back-end proxy. You can use Apache and mod_rewrite to create a proxy. Here is on how to do this or this link which is more detailed.
For example
ProxyPass /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
ProxyPassReverse /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
Creates a proxy at /api/gtalkbots which will returns the repose from gtalkbots.com

Your best solution is to use JSONP calls.
function jsonp(url, params, callback){
var script = document.createElement("script");
script.setAttribute("src", url+'?'+params+'&callback='+callback);
script.setAttribute("type","text/javascript");
document.body.appendChild(script);
}
function doit(data){
alert(data);
}
jsonp('http://domain.com', 'foo=bar', 'doit');
In the opposite side, the website you're contacting must be able to return a JSONP formatted response in order for this to work.

There are 2 ways to do this, depending on whether the callee will ship out JSONP or not:
1. If you can, use JSONP
JSONP is a way to bypass the cross domain policy by returning a function call, rather than a naked JSON object. The P stands for padding, essentially just the part that calls the function.
For this to work, the callee needs to return JSONP.
Regular JSON looks like this:
{a: 12, b: 15}
JSONP looks like this:
callback({a: 12, b: 15});
When the AJAX request completes, the callback function (which you define in your own code) will be executed and the JSON data passed to it as an object, thus bypassing the cross domain policy.
2. If JSONP is not supported, mirror the request through your own server
The second option is to pipe data through your own server. Your JavaScript makes a request from your server, and the server then mirrors that request to the remote server and pings back the result.
Since the AJAX request is now made to your own server you won't run afoul of the cross domain policy.
There are two downsides to this approach:
Two requests are now required which will slow the response time a little, though probably not much as server to server communication will probably be via a fat pipe.
Since all requests now originate from your server you may have problems with IP based rate limits. This is the case with Twitter API calls. You may be able to mitigate against this by caching results.

Related

Cross domain issue due between https and http page. Ajax call failing

I have a website say xyz.com. i want to make an ajax call from say(http://pqr.xyz.com) to https://abc.xyz.com. but the call is failing to execute due to cross domain problem. Is there any method to overcome this. How xan i access the page via https.
If you want to make cross domain calls, you need to use JSONP.
This means you can change the server code so that the headers shows this cross-domain call is authorized. Depending on your server language, you'll have to do something like this :
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Request-Method", "GET")
w.Header().Set("content-type", "application/x-javascript") // this one of course for json calls
Using JSONP instead of JSON will also mean that you'll enclose you JSON in a function call, for example
acceptServerAnswer({'thisis':'myjson'])
Use a server-side proxy or JSON
http://devlog.info/2010/03/10/cross-domain-ajax

Cannot make ajax call between servers that differ only in port in HTML5/jQuery/Chrome stack

The parts
I am developing against two Pylons servers and testing locally. One server is on port 5000 and is the called server. The other is on port 7000. The latter creates a cookie that specifies the same domain as used by the former server. Essentially, the first server uses credentials provided by the second server to impersonate the user.
The first server expects to find an auth token (a cookie, really) in its response.environ at run time. When I authenticate on the server on port 7000 and browser to a service on port 5000, the latter server uses the cookie created by the former and the app works.
The fly in the ointment is that the first server creates an HTML5 app that uses an ajax call to the second server, and I cannot get the cookie to be included in the ajax call. I believe that Chrome (the browser we are using/requiring for HTML5 support reasons) refuses to send the cookie for cross domain reasons: going from foo.net:7000 to foo.net:5000 is considered cross domain.
Oh, and the ajax call is through jQuery.
The question
Is there any way to make an ajax call from an HTML5 app created on a port in the same domain to a server in the same domain but a different port?
What I've tried or discard out of hand
I do not believe I can use dynamic script tag insertion because I am making the call from javascript and the HTML is generated on the client at runtime from other javascript. At least, I don't think that is a desirable solution.
I don't believe Access-Control-Allow-* is applicable because I am going from client to server, not the other way.
I've seen this on jQuery and ports in ajax calls. I've seen this, too.
I know about the same-origin policy.
And this does not work.
Agree with Michael that the simplest solution is JSONP. But even in JSONP you need to configure your server such that it supports JSONP. Many Servers deny this to keep their data secure and sound. JSONP expect your server to send data in the format that can be evaluated as the valid JSON. But its not the case in every JSONP Request and response. So, just watch out for that.
The absolutely simplest solution to this is to use JSON/P. I wish there were an easier, softer way to accomplish this, but I certainly haven't found one.

Best Practice for Handling AJAX requests from website to API provider

So, I implemented an API provider to be accessed by both web application and mobile applications.
Most likely this will not be a large scale project, but I want to maximize my learning experience and geek out where I can.
Anyway, from what I understand, it seems like it's better to put the API provider service and the actual website on separate domains to make scaling easier.
For example, twitter has the website twitter.com and api.twitter.com.
One immediate issue would be dealing with the cross-domain issue with AJAX.
From what I gather, there are 2 ways to implement cross-domain AJAX
JSONP: I heard about it, but don't know much beyond the name
Proxy Server: so, my website is build on top of ASP.NET MVC and I was thinking about creating a APIProxy controller to handle all cross-domain API requests.
That way, I would make an AJAX call via $.ajax(settings) and then pass in the website URL that corresponds to the APIProxy controller. The APIProxy controller would then make the appropriate POST server calls and process the JSON responses and return the response back to AJAX callback functions.
I heard about flXHR about I don't want to use Flash because devices like the iPad or any a lot of mobile browsers don't support Flash.
Anyway, I just wanted to ask what are some of the best practices in managing a website with the API provider on a separate domain or subdomain.
When you request some JSON, it returns an object or array. Script tags are not subject to the same-domain rule. So instead making an AJAX call, you would essentially do this:
<script src="Http://api.example.com?param1=something&etc"></script>
That would load the JSON, and it would execute as JavaScript.
...But a simple object or array "executing" by itself isn't very useful. So when you request the JSON, you also include the name of a callback function. If the provider sees that a callback was provided, instead of just returning JSON, it actually returns JavaScript: the JSON is passed to your function as an argument.
Then, when the script loads, your function (which you already defined) is called, and given the JSON to work with.
That's JSONP.
Bibliography
Newton, Aaron. "Request.JSONP." Clientcide. 7 Dec. 2009. Web. 28 Jan. 2011.

Ajax And REST: Can I send an ajax request to a REST service to recieve response?

I want to use mootools and SqueezBox class to handle a request to a RESTful service. I don't want to use any server-side script. I am using AJAX. I send a request to the following url using GET method.
http://www.idevcenter.com/api/v1/links/links-upcoming.json
but I receive a 404 error. Is it because cross-site scripting? here is my code:
SqueezeBox.initialize({handler:'url',ajaxOptions:{method:'GET'}});
$('a.modal').addEvent('click',function(e){
new Event(e).stop();
SqueezeBox.fromElement($('a.modal'));
});
In Firebug console, sometimes 'aborted' is shown and sometimes '404'.what is wrong with that?
XMLHttpRequest is subject to the Same Origin Policy; if the document your JavaScript is running within is not from the same origin as the service you're trying to call, the call will be disallowed for security reasons.
There is now a proposed standard for cross-origin resource sharing to address this. It may be that the service you're trying to use supports it; if so, using a browser that implements CORS (recent versions of Firefox and Chrome do, as do some others) may work. IE8 supports it but requires that you do extra work.
You cannot use XMLHttpRequest (that is, ordinary "ajax") to call a service on a server that is not in your domain.
You can, however, use the JSONP trick, which takes advantage of the fact that the browser will load Javascript from other domains. However, the service has to know that you're going to do that, and it has to understand the protocol. That particular service seems perfectly willing to give me a JSON response, but it doesn't pay attention when I give it a "callback" parameter. (I've tried both "callback" and "jsonp" and the JSON blob that comes back is the same, without a function call wrapper.)

Ajax and a restricted uri

I would like to make an ajax call to a different server (same domain and box, just a different port.)
e.g.
My page is
http://localhost/index.html
I would like to make a ajax get request to:
http://localhost:7076/?word=foo
I am getting this error:
Access to restricted URI denied (NS_ERROR_DOM_BAD_URI)
I know that you can not make an ajax request to a different domain, but it seem this also included different ports? are there any workarounds?
Have a certain page on your port 80 server proxy requests to the other port. For example:
http://localhost/proxy?port=7076&url=%2f%3fword%3dfoo
Note the url encoding on the last query string argument value.
You could use JSONP. This is where you specify a callback with the request, the response from your ajax request gets wrapped with the callback function name. Rather than using XmlHttpRequest you insert a tag into the HTML document with the URL. Then when the response is retrieved the callback function is called, passing the data as a parameter.
Check this blog post out for an example
This is a browser restriction. All javascript calls must be to the same server and port of the home of the script. This will require something server-side to get around. I.E. have the process at localhost forward the request to localhost:7076.
It sucks, but it's necessary... Basically what you're going to need to do is proxy your AJAX request through a local proxy - some server side script / page / whatever on the same domain you're on - receive the call and forward it on to the other resource server-side. There might be some IFRAME tricks you could do but I don't think they work very well...could be wrong though, been awhile.

Resources