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

时间:2022-08-23 10:20:05

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.

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

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

基本上,我想从“http://www.example.com”查看“http://mycakeapp.com/posts/views/1.xml”

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 :(

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

我尝试过使用iframe:它会加载登录屏幕 - 我登录后会加载当前页面(例如“http://www.example.com”)!即使iframe源是“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)

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

3 个解决方案

#1


0  

JSONP is definitely what you're looking for.

JSONP绝对是您正在寻找的。

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

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

#2


4  

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.

只需在PHP中创建代理脚本即可。让Ajax请求您的代理脚本,让您的代理脚本使用cURL在您的域中“转发”您的请求,只需让您的代理脚本回应您从cURL请求中获得的响应,您就可以了。

#3


3  

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

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

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

这是我用来调用另一个域的脚本,传递一个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);
?>

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

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

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

我通常将它放在我的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});
        }
    });
}

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.

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

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

传入baseURL变量,它应该包含基础“http:// server / theappname”,就像你的应用程序的url一样。

#1


0  

JSONP is definitely what you're looking for.

JSONP绝对是您正在寻找的。

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

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

#2


4  

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.

只需在PHP中创建代理脚本即可。让Ajax请求您的代理脚本,让您的代理脚本使用cURL在您的域中“转发”您的请求,只需让您的代理脚本回应您从cURL请求中获得的响应,您就可以了。

#3


3  

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

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

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

这是我用来调用另一个域的脚本,传递一个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);
?>

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

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

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

我通常将它放在我的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});
        }
    });
}

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.

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

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

传入baseURL变量,它应该包含基础“http:// server / theappname”,就像你的应用程序的url一样。