我很难使用Cake \ Network \ Response :: header方法设置Content-Type响应标头,如下所示:http://book.cakephp.org/3.0/en/controllers/request-response.html#setting-headers
基本上,除了Content-Type标头之外,我能够设置几乎任何标头(甚至是随机组成的标头)。这让我相信在我的控制器方法完成之后,核心应用程序中的其他地方正在编写Content-Type标头。
以下是一些代码:
控制器:
public function sseTest() {
$this->response->header([
'Cache-Control' => 'no-cache',
'Content-Type' => 'text/event-stream'
]);
$this->viewBuilder()->layout('sse');
$this->set('data', date("r"));
}
模板(sse_test.ctp):
data: <?= $data ?>
布局(sse.ctp):
<?= $this->fetch('content') ?>
最后,AppController:
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 0.2.9
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
/**
* Application Controller
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*
* @link http://book.cakephp.org/3.0/en/controllers.html#the-app-controller
*/
class AppController extends Controller
{
/**
* Initialization hook method.
*
* Use this method to add common initialization code like loading components.
*
* e.g. `$this->loadComponent('Security');`
*
* @return void
*/
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
}
/**
* Before render callback.
*
* @param \Cake\Event\Event $event The beforeRender event.
* @return void
*/
public function beforeRender(Event $event)
{
if (!array_key_exists('_serialize', $this->viewVars) &&
in_array($this->response->type(), ['application/json', 'application/xml'])
) {
$this->set('_serialize', true);
}
}
}
正如你所看到的,我在AppController中没有任何时髦,而且我把我的控制器方法简化为非常基本的,只返回一个格式化的日期。当我通过访问app.com/controller/sse-test访问此页面时,我得到的页面正是我所期望的:
data: Thu, 30 Jun 2016 01:18:03 +0000
问题在于,当我使用Chrome开发工具查看响应标头时,这就是我所拥有的:
HTTP/1.1 200 OK
Date: Thu, 30 Jun 2016 01:18:03 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache
Pragma: no-cache
X-DEBUGKIT-ID: 511a91a6-c2f7-47b6-85bb-39644994e0dd
Content-Length: 37
Keep-Alive: timeout=5, max=17
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
如您所见,Cache-Control标头已设置,但Content-Type标头不是我指定的标头。我很确定它被覆盖了,但我不知道在哪里。你们有没有一些关于我应该在哪里寻找的建议或者为什么会这样?
对于笑话,我创建了一个独立的PHP页面,如下所示:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$time = date('r');
echo "data: The server time is: {$time}\n\n";
flush();
?>
此页面完美地将服务器发送的事件提供给静态html页面,这最终是我的目标......但我想使用CakePHP框架...
我确定我错过了一些简单的事情,请让我知道你的想法。谢谢。
根据下面的第一条评论,我在“处理内容类型”页面上看了一下。我已将我的控制器修改为:
public function sseTest() {
$this->response->header([
'Cache-Control' => 'no-cache'
]);
//add text/event-stream type
$this->response->type('text/event-stream');
$this->viewBuilder()->layout('sse');
$this->set('data', date("r"));
}
我甚至看过Response类中的response-&gt; _mimeTypes变量,我的text / event-stream正在添加。如果我在设置内容类型后只打印出$this->response->type()
的结果,则会返回text/event-stream
。但是,当设置响应时,实际标头仍包含Content-Type: text/html; charset=UTF-8
。还有什么想法吗?