views:

59

answers:

4

I'm not sure why but I haven't really been able to find the right resource for this which helps me understand the best practice here, but say I have an application, that I want to make an Ajax request to another application.

Say app A's domain name is: www.example.com, and I want to make a request to www.someapplication.com

Can I do something like this? (jQuery in this case)

$.ajax({
  url: 'http://www.someapplication.com/items',
  dataType: 'json',
  data: "search=butter",
  success: function(data){
    console.log(data);
  }
});

When I go the address (http://www.someapplication.com/items?search=butter&format=json) in my browser it returns a 200 response and the content in the json format which I requested however when the above JS executes it receives a 200 response but no content.

Is this because my sever at someapplication.com is recognizing this as an XSS attack and denying a response?

One though I had is should the request go to a .js file? I've noticed this in the design of other applications, for example: http://www.someapplication.com/search.js... err rather what is wrong with my concepts, am I missing something huge here about XSS, and Ajax?

+1  A: 

What you're hitting is the same origin policy, the remote domain needs to support JSONP in order to work, otherwise XmlHttpRequest is prevented (by the browser) from seeing the content.

Once that's setup, in jQuery you'd trigger JSONP behavior by setting the dataType option to jsonp instead, like this:

$.ajax({
  url: 'http://www.someapplication.com/items',
  dataType: 'jsonp',
  data: "search=butter",
  success: function(data){
    console.log(data);
  }
});

This requests the content in an entirely different way, by adding a <script> element to the page...so the domain must support JSONP, otherwise you'll see some flavor of syntax error when the response comes back.

Nick Craver
+1  A: 

In the answer of Nick you fill see how to use JSONP. I want to add you a recommendation how to modify your $.ajax code to see that you have an error inside of success handler. I described it in http://stackoverflow.com/questions/3616823/jquery-ajax-error-handler-doesnt-work/3617710#3617710. Probably the bug in jQuery after the change http://dev.jquery.com/changeset/6432 will be fixed soon. Till the time you can use

success: function(data, textStatus, xhr){
    if (xhr.readyState === 4 && xhr.status === 0) {
        alert('"error flag\" is true. It means that we have a network error '+
              'or abortion (for example because of Same Origin Policy restrictions)');
    }
},
error: function(xhr, textStatus, errorThrown) {
    if (textStatus !== null) {
        alert("error: " + textStatus);
    } else if (errorThrown !== null) {
        alert("exception: " + errorThrown.message);
    } else {
        alert ("error");
    }
}

In this case you will see "exception: access denied" error in IE and

"error flag" is true. It means that we have a network error or abortion
 (for example because of Same Origin Policy restrictions)

error in other web browsers in case of Same Origin Policy error.

By the way in my experiments browser return xhr.status=0 and not 200 in case of Same Origin Policy error.

Oleg
+3  A: 

It's indeed due to the same origin policy. If you have control over the remote server, you can also just add HTTP Access-Control headers in the server side. This way you're basically controlling from the server side on whether the client who has fired the XMLHttpRequest is allowed to process the response. Any recent (and decent) webbrowser will take action accordingly.

Here's a PHP-targeted example how to set the headers accordingly.

header('Access-Control-Allow-Origin: *'); // Everone may process the response.
header('Access-Control-Max-Age: 604800'); // Client may cache this for one week.
header('Access-Control-Allow-Methods: GET, POST'); // Allowed request methods.

The key is Access-Control-Allow-Origin: *. This informs the client that requests originating from * (in fact, everywhere) is allowed to process the response. If you set it to for example Access-Control-Allow-Origin: http://example.com, then the webbrowser may only process the response when the initial page is been served from the mentioned domain.

A lot of existing JSON services also uses this, under each the ones of Google.

See also:

BalusC
+1  A: 

While cross domain XHR is not available in all browsers yet, you can do a gateway made from simple PHP file:

<?php
echo file_get_contents($_GET['url']);
?>

Then you just use proper url: gateway.php?url=http://www.someapplication.com/items. Maybe not ideal solution, but it works.

EDIT: Consider declaring in PHP file urls (or just domains) you want to use to avoid possible abuse of the gateway, e.g.:

<?php
$urls = array();
$urls[0] = 'http://www.someapplication.com/items';
echo file_get_contents($urls[$_GET['id']]);
?>
pepkin88