2013-04-17 99 views
1

我一直在和我的网站一起愉快地移动,直到本周,当我们开始看到一些错误发生时,事实证明这与我误解Cake的RequestHandler作品,但我还没有找到一个很好的解决方法。CakePHP RequestHandler返回RSS/JSON而不是HTML

我正在使用一种方法来查找和返回各种格式的内容,以便他们都住在相同的URL(也许这是我的错误,我需要将它们分开?)。所以,在我的控制,我有:

if ($this->RequestHandler->ext == 'rss') {

挑上的RSS提要。我也尝试使用isRss(),但改变了它,认为这是我的问题的根源。我的问题是这样的:

当从浏览器打到这个URL(我们称之为/blog)时,我通常会得到一个HTML响应。如果我打到/blog.rss,我会得到RSS回应。太好了。但是,如果我点击/blog地址,并将我的标头设置为Accepts: application/rss+xml;,则它将返回RSS,而不管文字.rss扩展名是否存在。这些页面被缓存,所以现在我的浏览器用户在请求/blog地址而不是HTML版本时最终看到RSS源的缓存版本。

我签入RequestHandler,事实证明它使用_setExtension()来设置基于Accepts头的ext值,即使没有'真正的'扩展名存在。这似乎没有被覆盖,所以看起来好像我不得不自己解析URL以查看是否确实存在扩展或者完全分离这些URL并且不允许来自地址空间的rss/json(例如,/blog/feed,/blog/json)。

有没有更好/更简单的方法来解决这个问题或者我错过了这个设置的方式?我认为ext是一个可靠的迹象表明有一个实际的扩展,但也许有另一种方式来寻找它?

+0

作为对此的快速修复,我在$ this->这里添加了一个strpos检查来查看扩展是否被实际设置。这将打破(404没有找到)目前正在访问/博客链接的rss读者,但比现在看到rss的人更好。 –

+0

嗯,你的'Router :: parseExtensions()'看起来像什么? – Nunser

回答

2

你完全正确。如果没有明确设置分机,那么将调用_setExtension函数,因此像/blog这样的网址将请求该函数,但如果您做/blog.rss,则不会调用_setExtension

无论如何,这只是为了表明这一点。继续。

_setExtension() docs

如果HTML是首选类型中的一种,没有内容类型的设置, 这是为了避免与喜欢html和几个 其他内容类型的浏览器的问题。

所以,我明白这里是:如果你通过htmlRouter::parseExtensions,则内容类型不会根据公认的头进行设置。检查出the code(行149)为您的版本的蛋糕,有一个if跳过扩展名的内容类型覆盖,如果您的首选类型有htmlxhtml

if (count($similarTypes) === 1 && !in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) { 
     $this->ext = array_shift($similarTypes); 
    } 

尝试做

Router::parseExtensions('html', 'rss' /*and other extensions if you want*/) 

,看看是否能解决您的问题。

+0

似乎这样做 - 即使我的接受只设置为RSS,也不再获取rss。我已经达到了该代码的顶峰,但猜测我掩盖了它的那一部分。谢谢! –

+0

花了我一段时间去了那部分。别客气 :) – Nunser