【问题标题】:CakePHP: How to create a routing "fall-back"CakePHP:如何创建路由“后备”
【发布时间】:2013-12-26 16:25:42
【问题描述】:

我们的 URL 结构一直在快速发展,我们的日志有时会出现 404 错误,这些错误来自试图访问旧的、不存在的 URL 的用户。我想保持日志干净,并避免向这些用户显示 404 页面。有没有办法设置一个“后备”路由,这样如果没有找到该操作,用户就会进入控制器的索引(或除错误页面之外的任何地方)。

我知道如何有条件地手动连接路由。到目前为止,我们就是这样处理这个问题的,但它是劳动密集型的,因为每次 URL 结构发生变化时我们都需要添加一个新的。

例如:

Router::connect('/old/url/:param', array('controller' => 'new', 'action' => 'index'), array('param' => '.*[^0-9/]+.*'));

如果我们能做这样的事情会容易得多:

Router::connect('/some_controller/ + ...anything that doesnt exist', array('controller' => 'some_controller', 'action' => 'index') );

这可能吗?

更新

为了澄清,我不简单地使用通配符的原因是:我需要连接/重定向的 URL 并不都遵循相同的模式。为了演示,这里有一些我正在尝试重定向的 URL...

example.com/a/b/ --> example.com/a/
example.com/a/b/34  --> example.com/a/
example.com/a/c/ --> example.com/a/

但我不想重定向这个...

example.com/a/d

所以我的问题并没有通过 Burzum 下面的建议(翻译成这个例子)解决:Router::redirect('/a/b/*' ...Router::redirect('/a/*' ...,因为这会错过应该定位的链接或应该(分别)定位的链接。

当然,我可以为我想要定位的每个链接编写新的连接/重定向路由,但避免这种麻烦是这个问题的重点。此外,它是一个完全“反应式”的解决方案,因为我需要在检查调试日志并查看对不存在的控制器/操作/的请求后应用新路由。我正在尝试积极主动并防止当事情发生变化时,我的日志会被错误的请求填满。

【问题讨论】:

    标签: php cakephp routing cakephp-2.0


    【解决方案1】:

    See the book for redirect routing。我不会为你复制和粘贴整个部分,所以我建议你阅读链接。

    根据您的评论,我假设您不理解答案或您有其他要求。您的问题如下:

    我们的 URL 结构发展迅速,有时我们的日志 填满来自试图访问旧的、不存在的用户的 404 错误 网址

    正确的解决方案是使用重定向和 HTTP 状态 301。以下部分来自官方文档,并修改了示例以帮助您理解它。

    重定向路由允许您发出 HTTP 状态 30x 重定向 传入路由,并将它们指向不同的 URL。这在以下情况下很有用 您想通知客户端应用程序资源已移动,并且 您不想为相同的内容公开两个 URL。

    Router::redirect('/old/url/*', array('controller' => 'some', 'action' => 'index'), array('status' => 301));
    

    Read about HTTP statuses, mostly 301.

    HTTP 响应状态码 301 Moved Permanently 用于 永久重定向,意味着当前链接或使用 URL 的记录 收到的 301 Moved Permanently 响应应该是 更新为响应的 Location 字段中提供的新 URL。 此状态代码应与位置标头一起使用。 RFC 2616 声明:

    • 如果客户端具有链接编辑功能,它应该更新对请求 URI 的所有引用。
    • 响应是可缓存的。
    • 除非请求方法是 HEAD,否则实体应包含一个小超文本注释,其中包含指向新 URI 的超链接。
    • 如果收到 301 状态代码以响应除 GET 或 HEAD 以外的任何类型的请求,客户端必须在重定向之前询问用户。

    更新:

    另外,这是一个完全“被动”的解决方案,因为我需要应用新的 检查调试日志并查看请求后的路由 不存在的控制器/动作/。

    嗯,这应该是有限数量的操作。所以你必须声明它们,至少对于每个控制器,并确保它匹配一组动作:

    Router::redirect('/a/:action/*', array('controller' => 'some', 'action' => 'index'), array('status' => 301, 'action' => 'action1|action2'));
    

    如果您想要匹配更具体的 URL,则必须找到可以匹配的模式,或者您必须声明每个路由/重定向。

    example.com/a/b/34

    这看起来更像是一条没有找到的特定记录。您应该有一个尝试获取数据的方法,在您的(希望)模型方法中抛出 NotFoundException 并在控制器中捕获它并使用 $this->redirect(array(...), 301);重定向它们。

    您应该在路由上使用 301 状态进行重定向的另一个原因是 SEO:如果您只是将相同的内容连接到多个 URL,您很可能会受到大多数搜索引擎的负面影响。

    【讨论】:

    • 我想你可能误解了我的问题。我已经知道如何重定向/连接路由。我不会再次复制和粘贴我的整个问题,所以我建议你重新阅读问题。
    • 我的答案是“尝试访问旧的、不存在的 URL!”的正确答案!因为在这种情况下,您应该使用状态 301(永久移动)进行重定向。对于另一部分,只需使用通配符 /some_controller/*。请参阅路由文档。
    • 我已阅读您的问题两次,我建议也阅读我的答案两次。这绝对是您问题的正确解决方案。只需在重定向路由中使用通配符...让我喂你。
    • 我不能像你显示的那样使用通配符。看看我上面的更新以获得解释。
    • 我做到了。那里有很多有用的信息,但听起来底线是没有办法设置在操作不存在时应用的默认路由/重定向。换句话说,除非我手动指定每个操作,否则我无法阻止不存在的操作看到 404 页面。对吗?
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2012-07-25
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2021-12-17
    相关资源
    最近更新 更多