PHP external API access fails, when called from another page on same domain?
<p>I'm trying to do a little cross-site scripting with Jquery and PHP/Symfony (<code>HttpFoundation</code> Component), but I can't get the server to return necessary data.</p>

<p>My goal is for JQuery to retrieve JSON from the local domain: PHP accessing an external API, server-side.  I have opened up the <code>Access-Control-Allow-Origin</code> header to <code>*</code> to allow CORS ok, and everything works fine directly with dummy data.  Using the JSON endpoint via JQuery fails, however.  Everything happens on the same domain.</p>

<p>So, this dummy JSON data renders fine, if I manually create a JSON response:</p>

<pre><code>$data = json_decode('{
        "foo": "bar",
        "items": [
            {
                "id": "1234",
                "foo": "bar",
                "baz": "bingo",
            },
            {
                "id": "4567",
                "foo": "blork",
                "baz": "fladdurk",
            }
    }', true);

$response = JsonResponse::create($data, 200);
$response-&gt;headers-&gt;set('Access-Control-Allow-Origin', '*');
$response-&gt;send();
</code></pre>

<p>The JSON shows up nice in my client at <code>http://localhost/json_endpoint?q=stuff</code>.  I get back a nice JSON string:</p>

<pre><code>{"foo":"bar","items":[{"id":"1234","foo":"bar","baz":"bingo"},{"id":"4567","foo":"blork","baz":"fladdurk"}]}
</code></pre>

<p>This works perfectly fine using JQuery on the front-end, as well.  The dummy data appears exactly the same, and I can work with it; presumably Symfony doesn't mind supplying the JSON when it's not from an external API.</p>

<p>Things start to get weird if I try a PHP request to an external API (which is where the data is supposed to come from):</p>

<pre><code>protected function url_tools__request($url, $timeout=10, $headers=array()) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //suppress output.
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $ch_exec = curl_exec($ch);
    curl_close($ch);
    return $ch_exec;
}

$url = "http://api.example.com/?q=more+stuff";
$headers = array("Accept:application/json");

$xsr = $this-&gt;url_tools__request($url, 10, $headers);
$data = [
    "foo" =&gt; "bar",

    // here's the rub
    "items" =&gt; json_decode($xsr, true),
];

$response = JsonResponse::create($data, 200);
$response-&gt;headers-&gt;set('Access-Control-Allow-Origin', '*');
$response-&gt;send();
</code></pre>

<p>With this live data, everything appears correctly in the client if accessed directly at <code>http://localhost/json_endpoint?q=stuff</code>. So the API is working fine. I get the exact same full JSON string as above:</p>

<pre><code>{"foo":"bar","items":[{"id":"1234","foo":"bar","baz":"bingo"},{"id":"4567","foo":"blork","baz":"fladdurk"}]}
</code></pre>

<p>But if I attempt to access this endpoint via JQuery AJAX (perhaps at <code>http://localhost/another_page.html</code>), I get back a JSON string without any "items":</p>

<pre><code>{"foo":"bar","items":[]}
</code></pre>

<p>My JQuery code looks like this:</p>

<pre><code>xhr = $.ajax({
    url: '/json_endpoint',
    data: {q: "more+stuff"},
    type: "GET",
    dataType : "json"
})
.done(function(data, textStatus, request) {
    console.log(data)
}
</code></pre>

<p>I have looked at my requests and responses from all angles, and the string resolved by PHP/Symfony is the same whether using dummy or actual (XSS) data.  I'm pretty sure there's not a race condition or anything.</p>

<p>Any idea what I'm doing wrong?  Thanks in advance.</p>