【问题标题】:Magento losing messages after redirectMagento 重定向后丢失消息
【发布时间】:2012-11-06 12:28:53
【问题描述】:

我对 magento 消息有疑问。我正在构建自定义模块,理论上应该能够限制对商店某些部分的访问。我创建了一个观察者,它挂钩controller_action_predispatch 事件并检查用户是否可以访问当前请求。如果无法访问该操作,则观察者重定向用户并设置错误信息。我想将重定向 url 设置为客户来自的页面,以避免点击整个商店。我正在查看HTTP_REFERER 并在设置时使用它,否则我会将客户重定向到主页。问题是在后一种情况下(主页重定向)一切正常,但是当我根据引用者设置 url 时,我在消息框中看不到错误消息。

来自观察者的代码($name 变量是一个字符串):

Mage::getSingleton('core/session')->addError('Acces to '.$name.' section is denied');
$url = Mage::helper('core/http')->getHttpReferer() ? Mage::helper('core/http')->getHttpReferer()  : Mage::getUrl();
Mage::app()->getResponse()->setRedirect($url);

我发现有趣的是,如果我对观察者文件进行任何更改并保存它,那么下一个失败并被重定向到引用 url 的请求会显示错误信息,但任何后续都会丢失消息。

我认为问题出在完整的 url 和我的本地安装(我正在使用 .local 域)中,但我尝试添加

$url = str_replace(Mage::getBaseUrl(), '/', $url);

但这没有帮助。

我也尝试使用 php header() 函数进行重定向,但没有任何结果。

所有缓存都被禁用。触发问题的工作流程如下:

  1. 我将转到任何可访问的页面(例如 /customer/account)
  2. 点击购物车链接(此帐户的购物车已禁用)
  3. 返回/customer/account,出现错误提示
  4. 再次点击购物车链接
  5. 返回 /customer/account 但没有错误消息

任何关于在哪里寻找的提示将不胜感激。

【问题讨论】:

  • 你可以停用所有缓存(如果是 magento EE,则 + FPC)看看是否是缓存问题?顺便说一句,我不明白你所有的解释,你明白会话错误消息在第一次显示后被删除?
  • 我扩展了描述,希望现在清楚了。

标签: magento


【解决方案1】:
//A Success Message
Mage::getSingleton('core/session')->addSuccess("Some success message");

//A Error Message
Mage::getSingleton('core/session')->addError("Some error message");

//A Info Message (See link below)
Mage::getSingleton('core/session')->addNotice("This is just a FYI message...");

//These lines are required to get it to work
session_write_close(); //THIS LINE IS VERY IMPORTANT!
$this->_redirect('module/controller/action');

// or
$url = 'path/to/your/page';
$this->_redirectUrl($url);

这将在控制器中工作,但如果您在输出已经发送后尝试重定向,那么您只能通过 javascript 来做到这一点:

<script language=”javascript” type=”text/javascript”>
window.location.href=”module/controller/action/getparam1/value1/etc";
</script>    

【讨论】:

    【解决方案2】:

    您的邮件丢失了,因为您在controller_action_predispatch 中使用了不合适的重定向方式。您的解决方案一方面会导致“消息丢失”,另一方面会浪费服务器的处理能力。

    当您查看Mage_Core_Controller_Varien_Action::dispatch() 时,您会发现您的解决方案不会停止当前操作的执行,但它应该通过重定向来完成。相反,Magento 将当前操作执行到最后,包括呈现您之前添加的消息。所以难怪为什么消息会在下一个客户端请求中丢失,Magento 之前已经渲染了它,服务器响应包括你的重定向。

    您将在Mage_Core_Controller_Varien_Action::dispatch() 中进一步看到,只有一种可能停止当前操作的执行并直接跳到重定向,即第428 行catch (Mage_Core_Controller_Varien_Exception $e) [...]。所以你必须使用Mage_Core_Controller_Varien_Exception,这是非常不受欢迎的,但你的目的唯一正确的解决方案。唯一的问题是,这个类在 Magento 1.3.2 中引入后有一个错误。但这很容易解决。

    只需创建您自己的派生自 Mage_Core_Controller_Varien_Exception 的类:

    /**
     * Controller exception that can fork different actions, 
     * cause forward or redirect
     */
    class Your_Module_Controller_Varien_Exception 
        extends Mage_Core_Controller_Varien_Exception
    {
        /**
         * Bugfix
         * 
         * @see Mage_Core_Controller_Varien_Exception::prepareRedirect()
         */
        public function prepareRedirect($path, $arguments = array())
        {
            $this->_resultCallback = self::RESULT_REDIRECT;
            $this->_resultCallbackParams = array($path, $arguments);
            return $this;
        }
    }
    

    所以您现在可以用它来真正干净地实施您的解决方案:

    /**
     * Your observer
     */
    class Your_Module_Model_Observer
    {
        /**
         * Called before frontend action dispatch
         * (controller_action_predispatch)
         * 
         * @param Varien_Event_Observer $observer
         */
        public function onFrontendActionDispatch($observer)
        {
            // [...]
    
            /* @var $action Mage_Core_Model_Session */
            $session = Mage::getSingleton('core/session');
            /* @var $helper Mage_Core_Helper_Http */
            $helper = Mage::helper('core/http');
            // puts your message in the session
            $session->addError('Your message');
            // prepares the redirect url
            $params = array();
            $params['_direct'] = $helper->getHttpReferer() 
                ? $helper->getHttpReferer() : Mage::getHomeUrl();
            // force the redirect
            $exception = new Your_Module_Controller_Varien_Exception();
            $exception->prepareRedirect('', $params);
            throw $exception;
        }
    }
    

    【讨论】:

      【解决方案3】:

      这会起作用,所以试试吧:

      $url = 'path/to/your/page';
      $this->_redirectUrl($url);
      return false;
      

      这意味着您不允许再次执行任何其他操作。

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 2014-03-31
        • 2013-06-19
        相关资源
        最近更新 更多