7

I can make a GET request from PHP and get the correct response. This is the function I use:

PHP

function httpGet($url)
{
    $ch = curl_init();

    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_HEADER, false);

    $output=curl_exec($ch);
    curl_close($ch);
    return $output;
}

A simple example:

$fakevalue='iamfake';
$url="http://fakeurl.com?fakeparameter=".$fakevalue;
$jsondata= httpGet($url);
$fake_array = json_decode($jsondata, true);
$weed_var=$fake_array['weeds']; // successfully obtained weed.

This function returns the response from the server.

Now I am trying the same HTTP GET request in AJAX, but I can't get the response.

Initially I thought the problem was with the JavaScript function that I use. Google provided with me lots of JavaScript functions for performing the HTTP GET request but they all had the same problem. The request returns an error instead of the data that I got when I used PHP.

JAVASCRIPT

var fakevalue = "iamfake";

var fake_data = {
    fakeparameter: fakevalue
};

$.ajax({
    url: "http://fakeurl.com",
    data: fake_data,
    type: "GET",
    crossDomain: true,
    dataType: "json",
    success: function(a) {
        $("#getcentre").html(a);
    },
    error: function() {
        alert("Failed!");
    }
});

Error from JavaScript

XMLHttpRequest cannot load http://fakeurl.com?fakeparameter=fakevalue. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.`

I know you are going to tell me to use CORS, but if it was because of the absence of 'Access-Control-Allow-Origin' header, then how did I get response for the same service in PHP?

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 9
    It's the **browser** who denies your request to a domain different than your current one. When you use PHP, the server running your PHP code acts as a client and performs a GET request. When a browser performs an AJAX request, the remote server (if not the same domain) has to explicitly allow it - the server sends `Access-Control-Allow-Origin` back. There's the difference and yes, CORS is the answer. – N.B. Sep 10 '14 at 10:41
  • Google Chrome, Mozilla Firefox, IE- I tried this in all these 3 browsers. Error is same. Then how is this because of browser?? @ N.B. –  Sep 10 '14 at 10:43
  • 1
    Quentin explained it really well in his answer. Every browser MUST implement this in order to conform to the standard, which exists mostly because of security. – N.B. Sep 10 '14 at 10:43
  • @Hi_Daddy — Because they standardised on a common security model. It's a feature, not a bug. – Quentin Sep 10 '14 at 10:44
  • 1
    Even reading http://en.wikipedia.org/wiki/Cross-origin_resource_sharing should have told you all you need to know already … you either need to learn how to do some basic research, or how to understand explanations on technical stuff in the first place. – CBroe Sep 10 '14 at 10:50
  • possible duplicate of ["No 'Access-Control-Allow-Origin' header is present on the requested resource"](http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-requested-resource) –  Sep 10 '14 at 10:54

3 Answers3

16

With PHP (or anything else running on your server, or a standalone application (including those installed as a browser extension)), you are requesting data from Bob's server using your credentials (your cookies, your IP address, your everything else).

With Ajax, you are asking Alice's browser to request data from Bob's server using her credentials and then to make that data available to your JavaScript (which can then send it back to your server so you can see it yourself).

Bob might give different data to Alice then he would give to you. For example: Bob might be running Alice's eBanking system or company intranet.

Consequently, unless Bob's server tells Alice's browser that it is OK to make that data available to you (with CORS), the browser will prevent your JavaScript from accessing that data.

There are alternatives to CORS, but they involve either distributing the data using a file type that isn't designed to be a data format (JSONP) (which also requires Bob's server to cooperate) or having your server fetch the data from Bob and then make it available through a URL on your server (or some combination of the two like YQL does) (which means that you get the data Bob will give to you and not the data Bob will give to Alice).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • SO....Is there any way by which I can tell Alice to give me the data that I am looking for?? I understood Bob is the culprit. But is there any way by which Alice can help me get data??? –  Sep 10 '14 at 10:49
  • 2
    Yes, gain access to Bob's server and add `Access-Control-Allow-Origin` -- just like the error message is telling you. – Mihai Stancu Sep 10 '14 at 10:49
  • If I set Access-Control-Allow-Origin to *, then every jack-ass with a web browser & internet connection can access the server or something like that...Right??? @Mihai Stancu –  Sep 10 '14 at 10:53
  • 1
    Like @MihaiStancu said - you need to have the server send `Access-Control-Allow-Origin` BACK. That proves the server recognizes you as valid user/authority. That means you need to detect (on Bob's server) that the request came from Alice's domain, and then you need to explicitly prove that Bob's server is OK with that. This handshake is done in the form of sending `Access-Control-Allow-Origin: alice-in-wonderland.com`. Had this not be in place, imagine the potential of abuse doable by using a script you got from somewhere (spyware screams here). – N.B. Sep 10 '14 at 10:53
  • 1
    @Hi_Daddy - don't use `*`, that lets everyone access it like you said. Use the domain you consider valid. – N.B. Sep 10 '14 at 10:54
  • Ok. got it. Now i am in development stage. So, I work from localhost server.@ N.B. –  Sep 10 '14 at 10:57
  • Could you explain how the request made via a browser to a different server is different from the request made via php to a different server? Why doesn't the same theory apply to php? It isn't that, only `javascript` files could run malicious code – Suhail Gupta Feb 10 '16 at 08:51
  • @SuhailGupta — "Could you explain how the request made via a browser to a different server is different from the request made via php to a different server? " — Yes. This answer explains that (except for the last paragraph which goes off on a tangent). – Quentin Feb 10 '16 at 08:53
  • "It isn't that, only javascript files could run malicious code" — No. That has nothing to do with it. – Quentin Feb 10 '16 at 08:53
1

Simple answer: PHP isn't affected by CORS. It is a restriction placed by the browser on client-side code, so that the accessed URL gets to allow or deny the request.

Scimonster
  • 32,893
  • 9
  • 77
  • 89
0

You are running into CORS, because you are doing an XMLHttpRequest request from your browser to a different domain than your page is on. The browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. Try this: http://www.html5rocks.com/en/tutorials/cors/

If you only want to launch a GET request, you might try using JSONP datatype="jsonp". Examples: http://www.sitepoint.com/jsonp-examples/

Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
  • 1
    As at now (May 26, 2017) `jsonp` is a not only a hack but insecure as well. Aside that, it works only for GET requests. It is no longer recommended particularly now that there are other clean alternatives and effective ways to tackle the challenge it (jsonp) seeks to address. – nyedidikeke May 26 '17 at 02:16