24

i have a problem... i try to get json api in "http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json"

when i try to offline mode(this means i copy that json API in notepad and call it in my localhost) with this code...

function getLast(){
        $.ajax({
            url:"http://localhost/tickets/json/api_airport.json",
            type:'GET',
            dataType:"json",
            success:function(data){console.log(data.results.result[1].category);}
        });
    }

it runs perfectly.:)

but when i try to real url ("http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json") with this code:

$.ajax({
            url:"http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json",
            type:'GET',
            crossDomain:true,
            beforeSend: function(x) {
                if(x && x.overrideMimeType) {
                    x.overrideMimeType("application/j-son;charset=UTF-8");
                }
            },
            success:function(data){console.log("Success");}
        });

then in my google chrome javascript console,there is an error like this : "XMLHttpRequest cannot load http://api.master18.tiket.com/search/autocomplete/hotel?q=mah&token=90d2fad44172390b11527557e6250e50&secretkey=83e2f0484edbd2ad6fc9888c1e30ea44&output=json. Origin (http://localhost) is not allowed by Access-Control-Allow-Origin."

i know, it must be cross domain problem, can someone help me? nb:some pieces of code, i got from stack overflow community....thank you :)

Gregorius Airlangga
  • 443
  • 2
  • 6
  • 12

3 Answers3

48

You've got two ways to go forward:

JSONP


If this API supports JSONP, the easiest way to fix this issue is to add &callback to the end of the URL. You can also try &callback=. If that doesn't work, it means the API does not support JSONP, so you must try the other solution.

Proxy Script


You can create a proxy script on the same domain as your website in order to avoid the cross-origin issues. This will only work with HTTP URLs, not HTTPS URLs, but it shouldn't be too difficult to modify if you need that.

<?php
// File Name: proxy.php
if (!isset($_GET['url'])) {
    die(); // Don't do anything if we don't have a URL to work with
}
$url = urldecode($_GET['url']);
$url = 'http://' . str_replace('http://', '', $url); // Avoid accessing the file system
echo file_get_contents($url); // You should probably use cURL. The concept is the same though

Then you just call this script with jQuery. Be sure to urlencode the URL.

$.ajax({
    url      : 'proxy.php?url=http%3A%2F%2Fapi.master18.tiket.com%2Fsearch%2Fautocomplete%2Fhotel%3Fq%3Dmah%26token%3D90d2fad44172390b11527557e6250e50%26secretkey%3D83e2f0484edbd2ad6fc9888c1e30ea44%26output%3Djson',
    type     : 'GET',
    dataType : 'json'
}).done(function(data) {
    console.log(data.results.result[1].category); // Do whatever you want here
});

The Why


You're getting this error because of XMLHttpRequest same origin policy, which basically boils down to a restriction of ajax requests to URLs with a different port, domain or protocol. This restriction is in place to prevent cross-site scripting (XSS) attacks.

More Information

Our solutions by pass these problems in different ways.

JSONP uses the ability to point script tags at JSON (wrapped in a javascript function) in order to receive the JSON. The JSONP page is interpreted as javascript, and executed. The JSON is passed to your specified function.

The proxy script works by tricking the browser, as you're actually requesting a page on the same origin as your page. The actual cross-origin requests happen server-side.

Nate Higgins
  • 2,104
  • 16
  • 21
  • i already use &callback=? but there is same...it means the api can't support jsonp :) – Gregorius Airlangga Oct 02 '12 at 02:08
  • Yes, so try the proxy script :) – Nate Higgins Oct 02 '12 at 02:10
  • 2
    hey friend...proxy script is working perfectly...thankyou sooo much... wohooooo!!! :) – Gregorius Airlangga Oct 02 '12 at 02:38
  • What is there to explain, it is very simple what a proxy does, just so this script, the details are not important. Minor thing: You forgot the closing tag ?> in the PHP script. – Gerard Jan 10 '13 at 17:00
  • 1
    Pages that just contain PHP do not need the `?>` tag. In fact, it's [discouraged](http://php.net/manual/en/language.basic-syntax.instruction-separation.php) – Nate Higgins Feb 14 '13 at 14:58
  • 1
    I'm using django-rest-framework, just tried the json-p way but it doesn't work. I'd like to try the proxy script, but I need one in django not in PHP. Anyone has one ready to use? – Andrea Grandi Jul 12 '13 at 09:09
  • @AndreaGrandi They're really easy to make. Just fetch the contents of the page with `urllib2`, and output it however you normally would with Django. I've never used Python for the web, so I can't really help you out with that. Good luck though. – Nate Higgins Aug 13 '13 at 16:33
4

I fixed this (for development) with a simple nginx proxy...

# /etc/nginx/sites-enabled/default
server {
  listen 80;
  root /path/to/Development/dir;
  index index.html;

  # from your example
  location /search {
    proxy_pass http://api.master18.tiket.com;
  }
}
jmervine
  • 723
  • 7
  • 15
2

a thorough reading of jQuery AJAX cross domain seems to indicate that the server you are querying is returning a header string that prohibits cross-domain json requests. Check the headers of the response you are receiving to see if the Access-Control-Allow-Origin header is set, and whether its value restricts cross-domain requests to the local host.

Community
  • 1
  • 1
Ben West
  • 660
  • 5
  • 17