3

I am trying to achieve this http://wiki.kolmisoft.com/index.php/MOR_API_login . I have enabled the settings in my server to allow API. The problem Javascript having is, my main website runs under domain website.com whereas the asterisk servers runs in voip.website.com. So when I try to invoke the url using jQuery, I get XMLHttpRequest cannot load http://voip.website.com/.../.../..... Origin http://sites is not allowed by Access-Control-Allow-Origin.

Am not sure what is the best way to achieve this. Any points will be of great help.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
BTR Naidu
  • 1,063
  • 3
  • 18
  • 45

2 Answers2

4

All browsers enforce the same-origin policy which includes the entire host (website.com vs. voip.website.com). You cannot process the JSON returned from an Ajax post unless the hosts are the same.

There is a workaround called JSONP. The trick is that you wrap the reply in a JavaScript function. You see, the same-origin policy only applies to data, not full-blown scripts themselves. So if the response is JavaScript instead of data, the browser thinks you need this script to run.

For example, say your response was going to be this JSON:

{
  firstName: 'Abed',
  lastName: 'Nadir',
  school: 'Greendale Community College'
}

Instead, you respond with this:

({
  firstName: 'Abed',
  lastName: 'Nadir',
  school: 'Greendale Community College'
})

The thing to note is that the parentheses before and after make it a JavaScript anonymous function rather than JSON data. All you do is receive that response and strip off the JavaScript code before and after.

Sound kludgey? It is, but everyone does it including Flickr, Google, Amazon, Facebook, and on and on.

Rap
  • 6,851
  • 3
  • 50
  • 88
2

You will need to use JSONP to wrap the data in a callback and mimetype it as text/javascript to circumvent the cross-domain policy.

What are some good examples of JQuery using JSONP talking to .net?

The title mentions .net, but the server-side environment isn't relevant to the client implementation.

A viable alternative is to setup a server side script on your own domain that will forward the request using CURL (or any other http lib) and then output the response to the script's XHR request. This method sets up a catchall between your client-side scripts and the remote domain you are trying to access, as curl or any other server-side http lib is not bound by cross-domain policy.

EDIT

I'm going to do a little more to detail my second approach since you say you need to send a post. Just as proof of concept, I'm going to use PHP to detail what needs to be done, but it should be simple to port this general idea over to another scripting language.

Let's say I can make a catchall script on your domain at www.yourdomain.com/data.php The logic in that file needs to read all my post vars out of the http request, put them into a curl instance as a request to a new domain, execute that request, and then output that requests' response back out to my ajax XHR so that it was like there never was an intermediary in the first place.

I like to use jscol's OOCurl to make the syntax for curl a little bit prettier.

<?
reqire_once('path/to/oocurl.php');
$c = new Curl('voip.otherdomain.com/api'); // instantiate with the url endpoint for the api
$c->post = True;
// Set the postfields for the child request to the same as the parent
$c->postfields = $_POST;
//Bust if there is an error and output that instead  
$c->failoneerror = True;
$response = $c->exec();
if($c->errno()){
  //there was an error, what was it?
  header('Status:' . $c->info(CURLINFO_HTTP_CODE));
  echo $c->error();
}else{
  //success, echo output
  header('Content-type: application/json');
  echo $response;
}
?>

Sending your ajax requests to this kind of a script will transparently hand them off to the other domain specified in the constructor to CURL. Please note here that I've assumed the return mimetype is json - you may need to adjust this to suit your API.

If you have authentication credentials for your api, you will need to code them into the request manually as additional post vars and also secure the endpoint using an hmac. This is really specific to how you are doing your client/server side interaction and goes a little bit outside the scope of the redirector... basically just make sure you have a server defined hash salt and have the digest send with your post request, to make sure that third parties can't simply post to your intermediary endpt.

EDIT

In case anyone stumbles in from Google, I made a library with my own take on this approach available here.

Community
  • 1
  • 1
DeaconDesperado
  • 9,977
  • 9
  • 47
  • 77
  • In my current situation, I have to invoke a HTTP POST using JSONP. But this post mentiones that it is not possible to ussue a POST using JSONP. Is my understand correct? http://stackoverflow.com/questions/3860111/how-to-make-a-jsonp-post-request-that-specifies-contenttype-with-jquery – BTR Naidu Apr 30 '12 at 20:56
  • Then your only option is to go with the second method I described, since you are trying to send data via ajax to the API rather than get it. Do you have the abillity to deploy some kind of script to your environment (IE you have ssh/ftp access and something like a LAMP stack installed?) – DeaconDesperado Apr 30 '12 at 20:59
  • I have full control of the system but the system itself is developed using RoR and I dont want to fiddle there. As stated in the wiki, I expect it to redirect upon successful login attempt. I did tried using the 2nd approach but problem I faced was, on successful login the voip.website.com returns the post login page which is captured by the ajax. Now I am struck here.. How to tell ajax to override the current page with the content of new page? Hmm.. Maybe I should not use ajax here.. Have to try some other approach..? – BTR Naidu May 01 '12 at 07:38
  • thanks for the detailed info. I shall experiment with your sample code and update you on my progress. – BTR Naidu May 01 '12 at 07:44
  • The proposed solution works for me but I am calling php using ajax and after a good response from voip.website.com the page does not redirect. Any clue how to fix this? – BTR Naidu May 01 '12 at 15:18
  • I setup a library to help using CURL for this purpose. Feel free to use. https://github.com/DeaconDesperado/forwardr – DeaconDesperado May 10 '12 at 20:38