1

我一直在愉快地移动我的网站,直到本周我们开始看到一些错误出现,这些错误与我对 Cake 的 RequestHandler 工作方式的误解有关,但我还没有找到一个好的解决方法。

我正在使用一种方法来查找和返回各种格式的内容,以便它们都存在于同一个 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() 来设置ext基于 Accepts 标头的值,即使不存在“真正的”扩展。似乎没有对此进行覆盖,所以看起来我要么被迫自己解析 URL 以查看是否真的有扩展名,要么完全分离出这些 URL 并且不允许来自/blog地址空间的 rss/json(例如, /blog/feed, /blog/json)。

有没有更好/更简单的方法来解决这个问题,或者我在这种设置方式中缺少的东西?我认为ext这是存在实际扩展的可靠迹象,但也许还有另一种寻找它的方法?

4

1 回答 1

2

你说对了一部分。如果没有明确设置扩展_setExtension,则调用该函数,因此类似 url 的请求将请求该函数,但如果您这样做,则不会被调用。/blog/blog.rss_setExtension

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

阅读_setExtension() 文档

如果 html 是首选类型之一,则不会设置任何内容类型,这是为了避免首选 html 和其他几种内容类型的浏览器出现问题。

所以,我在这里的理解是:如果你传递html给你的Router::parseExtensions,那么内容类型将不会根据接受的标题设置。检查您的 cake 版本的代码(第 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*/)

看看是否能解决你的问题。

于 2013-04-17T19:48:09.460 回答