【发布时间】:2011-11-14 16:19:45
【问题描述】:
我正在使用Restler 来实现一个简单的 REST API。现在,如果我需要通过 AJAX 从另一个域使用该 API,我将需要发送一个回调参数以及我的请求。 Restler 是否对此提供支持(我还没有找到任何真实的文档)?
【问题讨论】:
我正在使用Restler 来实现一个简单的 REST API。现在,如果我需要通过 AJAX 从另一个域使用该 API,我将需要发送一个回调参数以及我的请求。 Restler 是否对此提供支持(我还没有找到任何真实的文档)?
【问题讨论】:
对于任何从谷歌搜索到此页面的人,我在 github 上提交了一个问题,并得到了作者的大力支持。如果您熟悉 Restler 的构建方式,那么实现起来相当简单。
来自https://github.com/Luracast/Restler/issues/17
<?php
//jsonpformat.php
class JsonpFormat implements iFormat {
const MIME = 'text/javascript';
const EXTENSION = 'js';
/*
* JsonFormat is used internally
* @var JsonFormat;
*/
public $jsonFormat;
public static $functionName = 'parseResponse';
public function __construct() {
$this->jsonFormat = new JsonFormat ();
if (isset ( $_GET ['jsonp'] )) {
self::$functionName = $_GET ['jsonp'];
}
}
public function getMIMEMap() {
return array (self::EXTENSION => self::MIME );
}
public function getMIME() {
return self::MIME;
}
public function getExtension() {
return self::EXTENSION;
}
public function encode($data, $human_readable = FALSE) {
return self::$functionName . '(' . $this->jsonFormat->encode ( $data, $human_readable ) . ');';
}
public function decode($data) {
return $this->jsonFormat->decode ( $data );
}
public function setMIME($mime) {
//do nothing
}
public function setExtension($extension) {
//do nothing
}
}
?>
这应该与restler.php 文件保存在同一目录中。完成后,编辑网关 (index.php) 以包含此文件并将其添加为受支持的格式。示例:
<?php
require_once '../../restler/restler.php';
#set autoloader
#do not use spl_autoload_register with out parameter
#it will disable the autoloading of formats
spl_autoload_register('spl_autoload');
$r = new Restler();
$r->setSupportedFormats('JsonpFormat','JsonFormat', 'XmlFormat');
$r->addAPIClass('BMI');
$r->handle();
?>
【讨论】:
Defaults::$accessControlAllowHeaders 静态成员类型交易吗?
这对我们很有效: header('Access-Control-Allow-Origin: *');
在返回单个端点之前将此添加到控制器方法,添加到该分支或更高级别中所有端点的控制器类构造函数,以允许它在站点范围内使用。
如果您只允许某些网站访问,请使用 header('Access-Control-Allow-Origin: example.com') 或类似 header('Access-Control-Allow-Origin: '.$remote_domain) 的内容。其中 $remote_domain 是根据一些传入的令牌等动态设置的。查看跨域资源共享 (CORS),了解为什么要限制 * 通配符的使用。
<?php
class Say {
__construct(){
header('Access-Control-Allow-Origin: *'); //Here for all /say
}
function hello($to='world') {
header('Access-Control-Allow-Origin: *'); //Here for just /say/hello
return "Hello $to!";
}
}
以上内容适用于 GET 和 POST,其他操作需要来自 restler 的一些额外的标头信息。下面是一些例子:
header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT, OPTIONS'); header('Access-Control-Allow-Headers:whatever_headers_you_allow, header1, header2');
对于 IE9 及以下版本,您需要 JSONP hack。 Restler 有扩展 iFormat 类以包装 API 输出 JASONP 样式的示例。
查看 Mozilla hacks 以了解有关 CORS 的详细信息。 http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/ 并查看OPTIONS in PHP REST API
【讨论】:
我在这里补充一下,如果由于某种原因你不想使用 JSONP,你可以简单地添加:
header('Access-Control-Allow-Origin: *');
根据 punkael 的第一个答案(他没有指定在 Rester 中执行此操作的位置)。将此行添加到 sendData($data) 函数中的 restler.php,其中 Restler 将标头数据添加到响应中。这从第 378 行开始。
但请小心,因为这将允许任何域从您的 API 中获取数据。
【讨论】: