5

我想用 CakePHP 提供 JSONP 内容,并且想知道这样做的正确方法是什么。

目前我可以按照这个 CakePHP指南自动提供 JSON 内容。

4

3 回答 3

5

好的,我在这个网站上找到了解决方案。基本上,您可以使用以下方法覆盖 afterFilter 方法:

public function afterFilter() {
    parent::afterFilter();

    if (empty($this->request->query['callback']) || $this->response->type() != 'application/json') {
        return;
    }

    // jsonp response
    App::uses('Sanitize', 'Utility');
    $callbackFuncName = Sanitize::clean($this->request->query['callback']);
    $out = $this->response->body();
    $out = sprintf("%s(%s)", $callbackFuncName, $out);
    $this->response->body($out);
}

我希望它也对其他人有所帮助。

于 2013-02-03T01:21:43.243 回答
4

我还没有找到如何使用 CakePHP 2正确返回 JSONP 的完整示例,所以我将把它写下来。OP 要求正确的方法,但他的答案没有使用 2.4 中现在可用的本机选项。对于 2.4+,这是正确的方法,直接来自他们的文档:

  1. 设置您的视图以接受/使用 JSON(文档):

    • 添加Router::parseExtensions('json');到您的routes.php配置文件中。这告诉 Cake 接受.jsonURI 扩展
    • 添加RequestHandler到您将要使用的控制器中的组件列表
    • Cake 在这里变得很聪明,现在为您提供普通请求和 JSON/XML 等请求的不同视图,如果需要,您可以灵活地返回这些结果。您现在应该能够通过以下方式访问控制器中的操作:
      • 使用 URI /controller/action(将使用 中的视图/view/controller/action.ctp),或者
      • 使用 URI /controller/action.json(将使用 中的视图/view/controller/json/action.ctp
  2. 如果您不想定义这些视图,即您不需要做任何进一步的处理,并且响应已准备就绪,您可以告诉 CakePHP 忽略视图并立即使用_serialize. Using_serialize将告诉 Cake 以正确的格式(XML、JSON 等)格式化您的响应,设置标题并根据需要返回它,而无需执行任何其他操作(文档)。要利用这个魔法:

    • 像视图变量一样设置要返回的变量,即$this->set('post', $post);
    • 告诉 Cake 通过调用将其序列化为 XML、JSON 等$this->set('_serialize', array('posts'));,其中参数是您刚刚在上一行中设置的视图变量

就是这样。所有标头和响应都将由 Cake 接管。这只是让 JSONP 开始工作(文档):

  1. 通过设置告诉Cake 将请求视为JSONP 请求$this->set('_jsonp', true);,Cake 将查找回调函数名称参数,并格式化响应以使用该回调函数名称。从字面上看,设置一个参数可以为您完成所有工作。

因此,假设您已将 Cake 设置为接受.json请求,这就是您使用 JSONP 时的典型操作:

public function getTheFirstPost()

    $post = $this->Post->find('first');

    $this->set(array(
        'post' => $post,                 <-- Set the post in the view
        '_serialize' => array('post'),   <-- Tell cake to use that post
        '_jsonp' => true                 <-- And wrap it in the callback function
    )
);

和 JS:

$.ajax({
    url: "/controller/get-the-first-post.json",
    context: document.body,
    dataType: 'jsonp'
}).done(function (data) {
    console.log(data);
});
于 2015-03-10T12:27:09.860 回答
0

对于 CakePHP 2.4 及更高版本,您可以改为这样做。

http://book.cakephp.org/2.0/en/views/json-and-xml-views.html#jsonp-response

所以你可以简单地写:

$this->set('_jsonp', true);

在相关行动中。

或者你可以简单地写:

/**
 *
 * beforeRender method
 *
 * @return void
 */
    public function beforeRender() {
        parent::beforeRender();
        $this->set('_jsonp', true);
    }
于 2013-10-26T07:00:26.123 回答