2

I made a simple API in PHP. This API echo's an object using json_encode.

Per example:

echo json_encode($obj);

I am using jQuery to retrieve the information from this API. When testing the script and the API, they where both running on the same server. And everything worked fine.

An example of the jQuery:

$.ajax({

    url: "php/api/test.php"
    dataType: "json",
    type: "POST",
    succes: function(data) {
        console.log("success");
    },
    error: function(response) {
        console.log("error");
    }
});

Now this worked fine. However since the API is running on an external server this does not work anymore (yes I changed the url to the correct one).

I had to alter the API and the javascript in order to use JSONP Before jQuery would finally receive the information from the API.

My jQuery now is:

$.ajax({

    url: "http://externalserver/php/api/test.php"
    dataType: "jsonp",
    type: "POST",
    succes: function(data) {
        console.log("success");
    },
    error: function(response) {
        console.log("error");
    }
});

The PHP will return this in order to work:

echo $_REQUEST['callback'] . '(' . json_encode($obj) . ')';

Now I actually would rather use JSON in stead of JSONP.

I understood that I need to alter the PHP file to let the API accept incomming requests from an external script like mine.

Can you tell me what it is I need to do?

BonifatiusK
  • 2,073
  • 5
  • 22
  • 40
  • You can use ajax for this – Shijin TR May 13 '13 at 09:08
  • I dont understand your question please specify what you are looking for and what you need. – Reflic May 13 '13 at 09:09
  • 2
    @shin: What do you think the OP is doing? JSON, jQ PHP, external server... it all points to AJAX, doesn't it? To the OP: Are you asking how to get X-domain XhttpRequests to work? – Elias Van Ootegem May 13 '13 at 09:12
  • Now that the call is to an external server (which I assume is on a different to domain to the calling javascript) you can only use a JSONP or CORS request. If you do not wish to use those methods then you must use a server-side request to get your data. – Rory McCrossan May 13 '13 at 09:12
  • I changed the question hoping it would clearify things @RoryMcCrossan: In java you can add something to the page header in order for him to accept normal json (not jsonp) calls to the server (indeed on an other domain). – BonifatiusK May 13 '13 at 09:27

2 Answers2

4

AFAIK, you're running into the cross-domain problem of AJAX requests. The easiest, and most cross-browser fix for this issue is using JSONP. There is nothing definitive you can in your PHP script that will fix this issue, because it is, in part, down to the client. Not a lot of people know how to disable the cross-domain ban either, for testing purposes, you could consider disabling your browser security.

Just use JSONP, honestly, it'll save you a lot of headaches. If you are already using jQuery, you might as well use its best feature (the cross-domain thing).
If you're ever planning on ditching jQuery, read up on what CORS requests entail.

Community
  • 1
  • 1
Elias Van Ootegem
  • 67,812
  • 9
  • 101
  • 138
  • 1) disable browser security = bad, 2) JSONP = OP does not want to use it, also it is very restricted e.g. no POST Requests possible (which often is needed if you are working with webservices) 3) "There is nothing you can do to your PHP script that will fix this issue" = wrong - you just need to set some headers to fix this – Christoph May 13 '13 at 09:22
  • @Christoph: 1) You can do that, I never recommended it. 2) OP doesn't want to use it, whereas I said it'll be the easiest fix given his situation. If OP is testing something, that will later run on same server, JSONP is the easiest thing to use. 3) Fair enough, though that would imply being able to send an initial request. Sometimes, that isn't possible – Elias Van Ootegem May 13 '13 at 09:26
  • 2) using JSONP will require code changes on both server and client side and will still introduce various limitations which you cannot bear when writing a (REST) Webservice (which might be the case for the OP since he mentioned an selfmade API). Setting the header only requires change in the serverside code. The browsers checks for those headers, so I don't understand your point 3 – Christoph May 13 '13 at 09:29
  • 1
    I understand what @EliasVanOotegem is saying. It might not be wise to alter the Access-Control for safety reasons. Maybe it is good to add the pro's and con's in a specific topic or answer? – BonifatiusK May 13 '13 at 09:53
  • @BonifatiusK if you argue this way, than you have the same problems with JSONP too, which effectively is a workaround for the SOP, Browsers obey to (and you cirumvent with JSPON). Better use the clean way and declare the CORS-Header with the exact domain you expect your calls from (`*.yourdomain/*`). – Christoph May 13 '13 at 10:29
  • @Christoph: I was wrong to assume OP is currently testing the code. I personally find your answer the better of the two. But the OP did get my thinking: I'm a bit paranoid about changing the access control server-side. Yes, JSONP might have similar issues, but it is (as you said yourself), more limiting and limited (ie more controllable) – Elias Van Ootegem May 13 '13 at 10:36
3

You need to set a parameter in your header that allows CrossOriginRessourceSharing (CORS) or else your browser will block those calls due to the Same-Origin Policy (SOP). If you set the allow-origin-response-header within your php, everything should work as intended.

Putting

header('Access-Control-Allow-Origin: *');  

at the top of your test.php will fix your problem. (Or preferably replace * with the specific domain your calls come from).

Christoph
  • 46,101
  • 18
  • 92
  • 121