如何使用CakePHP和jQuery实现跨域Ajax请求?

时间:2009-03-19 03:19:49

标签: jquery xml ajax cakephp cross-domain

我正在使用CakePHP作为我的项目,我正在生成XML视图,以便我可以从外部网站与它们(CRUD)进行交互。 CakePHP网站上需要进行身份验证。

基本上,我想从“http://mycakeapp.com/posts/views/1.xml

中查看“http://www.example.com

但是,在使用jQuery的ajax函数时出现此错误:访问受限制的URI被拒绝“代码:”1012 。谷歌搜索似乎可能尝试JSONP是一个选项..但它不是原生的蛋糕,因此我宁愿使用xml :(

我尝试过使用iframe:它会加载登录屏幕 - 我登录后会加载当前页面(例如“http://www.example.com”)!即使iframe源是“http://mycakeapp.com/posts/views/1.xml

以前有人解决过这个问题吗?

更新:为了更具体一点,我想创建一个与我的网站(基于CakePHP构建)通信的书签,因此url代理方法不起作用(但感谢建议)

3 个答案:

答案 0 :(得分:4)

只需在PHP中创建代理脚本即可。让Ajax请求你的代理脚本,让你的代理脚本使用cURL在你的域中“转发”你的请求,只需让你的代理脚本回应你从cURL请求得到的响应,你就会好起来。

答案 1 :(得分:3)

正如mmattax所提到的,最简单的方法是使用代理脚本。

这是我用来调用另一个域的脚本,并将其传递给urlencoded proxy_url参数。

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);
?>

在您的情况下,您可能希望更改错误处理位以返回应用程序可以解析的有效xml位。

我通常把它放在我的webroot中,然后用javascript调用它:

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});
        }
    });
}

上面的示例javascript函数用于从我们的地图服务器返回一个简单的url字符串,我们不关心它是否失败所以没有onFailure等,它主要是Prototype,但我相信你明白了关于它如何使用代理脚本。

传入baseURL变量,它应该包含基础“http://server/theappname”,就像您的应用的网址一样。

答案 2 :(得分:0)

JSONP绝对是您的目标。

也许以下页面可以帮助您:http://www.ibm.com/developerworks/xml/library/x-xml2jsonphp/