【问题标题】:Luracast Restler callback parameter for cross-domain AJAX跨域 AJAX 的 Luracast Restler 回调参数
【发布时间】:2011-11-14 16:19:45
【问题描述】:

我正在使用Restler 来实现一个简单的 REST API。现在,如果我需要通过 AJAX 从另一个域使用该 API,我将需要发送一个回调参数以及我的请求。 Restler 是否对此提供支持(我还没有找到任何真实的文档)?

【问题讨论】:

    标签: php rest


    【解决方案1】:

    对于任何从谷歌搜索到此页面的人,我在 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();
    ?>
    

    【讨论】:

    • 不错。我想知道,这是否安全:self::$_GET ['jsonp']?
    • Luracast 不应该允许我们设置Defaults::$accessControlAllowHeaders 静态成员类型交易吗?
    【解决方案2】:

    这对我们很有效: 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

    【讨论】:

    【解决方案3】:

    我在这里补充一下,如果由于某种原因你不想使用 JSONP,你可以简单地添加:

    header('Access-Control-Allow-Origin: *');
    

    根据 punkael 的第一个答案(他没有指定在 Rester 中执行此操作的位置)。将此行添加到 sendData($data) 函数中的 restler.php,其中 Restler 将标头数据添加到响应中。这从第 378 行开始。

    但请小心,因为这将允许任何域从您的 API 中获取数据。

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 2018-10-10
      • 1970-01-01
      • 2014-12-20
      相关资源
      最近更新 更多