Question

I am using CakePHP for my project, and I am generating XML views so that I can interact with them (CRUD) from an external website. There is authentication required on the CakePHP website.

Essentially, I want to view "http://mycakeapp.com/posts/views/1.xml" from "http://www.example.com"

However, I get this error when using jQuery's ajax function: Access to restricted URI denied" code: "1012. It seems from googling that maybe trying JSONP is an option .. but its not native to cake and hence I'd rather use xml :(

I've tried using an iframe: it loads up the login screen - and after I login, it loads the current page (e.g. "http://www.example.com")! Even though the iframe source is "http://mycakeapp.com/posts/views/1.xml"

Has anyone tackled this problem before?

Update: To be a bit more specific, I would like to create a bookmarklet that communicates with my website (built on CakePHP), so a url proxy method won't work (but thanks for the suggestion)

Was it helpful?

Solution

JSONP is definitely what you're looking for.

Maybe the following page could help you: http://www.ibm.com/developerworks/xml/library/x-xml2jsonphp/

OTHER TIPS

Simply make a proxy script in PHP. let the Ajax request your proxy script, have your proxy script "forward" your request across the domain by using cURL, simply have your proxy script echo out the response you get from your cURL request, and you will be good to go.

As mmattax mentioned, the easiest way to do this is by using a proxy script.

Here's a script I use to call out to another domain, passing it an urlencoded proxy_url parameter.

url_proxy.php

// Is it a POST or a GET?
$url = ($_POST['proxy_url']) ? $_POST['proxy_url'] : $_GET['proxy_url'];

// Open the Curl session
$session = curl_init($url);

// If it's a POST, put the POST data in the body
if ($_POST['proxy_url']) {
    $postvars = '';
    while ($element = current($_POST)) {
        if (key($_POST) != 'proxy_url') {
            $postvars .= key($_POST).'='.$element.'&';
        }
        next($_POST);
    }
    curl_setopt ($session, CURLOPT_POST, true);
    curl_setopt ($session, CURLOPT_POSTFIELDS, $postvars);
}

// Don't return HTTP headers. Do return the contents of the call
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);

// Make the call
$response = curl_exec($session);

// Return the response
if (curl_errno($session)) {
    $error_message = curl_error($session);
    echo 'Error: '.$error_message;
} else {
    echo $response;
}

curl_close($session);
?>

In your case you may want to alter the error handling bit to return a valid bit of xml that your app can parse.

I usually put this in my webroot, and call it from javascript with something like:

function showMapLegend(baseURL, layer) {
    var url = 'http://our-map-server/get-a-legend.php?layer='+layer;
    var dt = new Date();
    var proxy = baseURL + '/url_proxy.php?currDate='+dt.getTime()+'&proxy_url=';
    url = proxy + encodeURIComponent(url);

    new Ajax.Request(url, {
        method: 'get',
        onSuccess: function(transport) {
            $('map-legend-img').src = transport.responseText;
            new Effect.Appear('map-legend', {duration: 0.5});
        }
    });
}

The example javascript function above is used to get a simple url string back from our map server, we don't care if it fails so there's no onFailure etc, and it's mostly Prototype, but I'm sure you get the idea on how this uses the proxy script.

The baseURL variable is passed in, it should contain the base "http://server/theappname" like url for your app.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top