我们在 LEMP 服务器上有一个 Magento 网站 (1.6.2),我们已经运行了两年多。最近我们做了一些改变;

  • 将整个网站更改为 HTTPS。
  • 创建了所有新类别并摆脱了旧类别,但保留了相同的产品
  • 以表单创建服务器重定向;

    location/this/old/类别{reprite ^(this/old/ectory)/?(。*)$ https://oursite.co.uk/new/category永久 2 美元;}

这适用于类别页面及其中的任何产品,我们认为我们都很好!

然而,Google WMT 开始显示大量未关注的 URL,因此我们进行了调查,发现许多产品都被奇怪地重定向并导致重定向循环。

在 Chrome 的网络选项卡中,我可以看到,当您转到某些产品的旧 URL 时,服务器重定向就会启动,您会得到正确的响应。然而,接下来是(看似无限的)重定向,其格式为:

随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/随机/旧/类别/产品名称

基本上,它会不断地为每个请求添加“随机/旧/类别”。我们的服务器主机坚持认为 a) Magento(所以不是他们的问题)和 b) 应该有一个前面的斜杠。

我找不到任何会导致此问题的设置。

  • “使用 Web 服务器重定向”设置为“是”。
  • 我在数据库的文本转储上使用了“grep”来尝试查找受影响的 URL 之一(没有任何乐趣,而且我确信由于第 1 点,情况不会如此)。
  • 我还用细齿梳手动浏览了管理区域,但看不到任何可能的原因。

我希望这是足够的信息。谁能告诉我除了在服务器上之外,重定向可能发生在哪里?

更新:

正如 Douglas 指出的那样,新的 URL 似乎也被重定向,但我已经检查了该站点(和其他站点)的 .conf 文件,并且没有任何规则会导致这种情况。

更新2:

我已经有了一点小小的突破。看起来,当Magento在它重定向到的类别中找不到产品时,它会一直循环下去。为什么它会这样做而不仅仅是 404 对我来说是个谜,所以对此提供帮助也很好!

更新3:

3年时间,一次服务器搬迁,大量经验,后来升级到CE 1.9.3.8,我想我已经取得了突破!

我现在确定这是一个 Magento 路由问题,就像添加一个 die(); index.php 中的行不会发生重定向循环。

我将这个日志代码(可以在互联网上的多个地方找到)添加到 Mage_Core_Controller_Varien_Front 班级:

Mage::log('----Matching routers------------------------------');
Mage::log('Total ' . count($this->_routers) . ': ' . implode(', ', 
array_keys($this->_routers)));
while (!$request->isDispatched() && $i++<100) {
    Mage::log('- Iteration ' . $i);
    $requestData = array(
        'path_info' => $request->getPathInfo(),
        'module' => $request->getModuleName(),
        'action' => $request->getActionName(),
        'controller' => $request->getControllerName(),
        'controller_module' => $request->getControllerModule(),
        'route' => $request->getRouteName()
    );

    $st = '';
    foreach ($requestData as $key => $val) {
        $st .= "[{$key}={$val}]";
    }
    Mage::log('Request: ' . $st);
    foreach ($this->_routers as $name => $router) {
        if ($router->match($this->getRequest())) {
            Mage::log('Matched by "' . $name . '" router, class ' . 
    get_class($router));
            break;
        }
    }
}

通过一些研究和理解此类中的代码;Magento 从系统(核心或模块)中寻找路由器来负责 $request 一旦匹配就会发出调度信号。

通过上面的日志代码,我得到了路由器列表,但没有信息 $requestData 表明路由器从未调度过的数组。

在每个列出的路由器中,我去了 控制器/路由器.php 文件并找到 match(Zend_Controller_Request_Http $request) 方法。在此方法返回 true(表示匹配)之前的行中,我添加了一个简单的回显行,例如:

echo "matched in the xxx module"; die();

这导致我找到负责的路由器,然后我 怀疑 这不是在匹配后调度请求,因此它只是不断循环。负责的模块是 MageWorx_SeoSuite, ,我怀疑它过去已被第三方修改过,因为我在网上找不到任何参考资料。需要进行更多调查,我会尽快进行。

有帮助吗?

解决方案

事实证明, match(Zend_Controller_Request_Http $request) 在 MageWorx_SeoSuite 路由器中有一个 switch 语句,它解决了 CMS, Rss, Category, Category_layer 和其他路线。

问题在于 default (读:产品) 此 switch 语句的情况。这是一个非常独特的情况(这解释了为什么它只影响了少数产品)。

它会;

  • 检查 url 是否结尾(即:产品 urlKey)进行了重写并 如果不;
  • 检查所述产品的最低级别类别是否已重写并 如果不;
  • 通过 ID 加载产品并从以下位置获取规范 Url MageWorx_SeoSuite 助手类;
  • 发送到规范 Url 的重定向,并根据配置设置使用先前定义的 HTTP 响应代码更新响应。
  • exit();

如果前两个条件语句中的任何一个是 错误的;该方法将 return false; (IE:路由器不匹配)。但是,如果前两个条件都评估为 true 并通过了其他一些检查(规范 Url 不为空等);该语句将发送重定向,然后简单地 exit();.

我对整个路由方法很陌生,但我相信这有一些问题;

  1. 该方法没有为条件的所有路由返回布尔值(例如,如果产品及其直接类别没有重写)。
  2. 该方法将“匹配”但从未匹配 dispatch'd。
  3. 这是基于我有限的(本科)知识,但是:这似乎是非常糟糕的软件设计。

此时值得指出,因为我不想在没有事实的情况下对 MageWorx 进行分类:我非常确定这段代码在过去 5 年里已经被更改过(可能有几家第三方公司对此负责)。

总之: :我注释掉了 default: switch 中的 case 语句,以便 Magento 核心承担责任。罪魁祸首的网址现在转到 404, no-route 页面,这是理想的,因为它们都是旧的不存在的路径。我通常不会以这种偶然的方式更改模块代码,但我已经很好地记录了这一点,而且我们很幸运,我们网站的新版本正在开发中,因此“修复”是暂时的。

许可以下: CC-BY-SA归因
scroll top