如何在CakePHP中提交之前保存会话中的当前URL?

问题描述

我在我的网站上有几种联系方式。主要页面(来自“联系”部分)通过我的“客户”控制器中的一个动作工作,我在其他页面中还有其他几种表单(在其他控制器的视图中,我将表单发送给主要控制器的动作,然后重定向到原始表单),一切正常。电子邮件通知已发送,记录已保存到我的数据库中。

问题是在我实现了Recaptcha插件之后出现的。该插件可以正常工作(如“如果您检查Recaptcha,它会按预期工作;否则,它会显示错误消息”),但是当我使用“辅助”表单时,而不是重定向回原始的起始页面,它总是将我重定向到该主控制器操作的页面(并且我在隐藏字段中释放了信息,在该字段中,我正在注册客户端当前正在使用的特定表单)。

我尝试停用重定向,但这不起作用。用户仍然被“带到”主控制器页面

然后,我搜索了一些解决方案(在google和堆栈溢出中),并且在类似的问题中出现了答案“将当前的URL保存到会话中并加载以进行重定向”,这很有意义。 但是,当我尝试保存它时,发现会话是在之后开始保存的,因此我的会话是在跳转到主要操作之后而不是在提交表单之前保存该URL。 / p>

我尝试将会话保存在beforeFilter和beforeRender中,但仍然无法正常工作。

在将表单提交给主要操作之前,我该怎么做才能将URL保存在会话中?

我的主控制器的动作:

class ClientsController extends AppController
{
  public function beforeFilter(\Cake\Event\Event $event) 
  {
    parent::beforeFilter($event);
    $route = $this->request->getParam('_matchedRoute');
    $session = $this->request->getSession()->write('Origin',$route);
  }

  public function contact()
  {
    $cliente = $this->Clients->newEntity();
        
    if ($this->request->is('post')) {
      if ($this->Recaptcha->verify()) {
        // Verify recaptcha
        $client = $this->Clients->patchEntity($client,$this->request->getData());
        if ($this->Clients->save($client)) {
          $email = new Email();
          $email->setProfile('default');
          $email->setFrom($client->email)
            ->to('contact@server.com')
            ->setSubject('Contact form sent from: ' . $client->source)
            ->setEmailFormat('both')
            ->setViewVars([
              'source' => $client->source,'name' => $client->first_name . ' ' . $cliente->last_name,'company' => $client->company,'localphone' => $client->local_phone,'email' => $client->email,'comments' => $client->comments
            ])
            ->viewbuilder()->setTemplate('default','default');

          $email->send([$client->comments]);

          $this->Flash->success('Youyr message has been sent. We'll contact you soon!');                
          $this->redirect($this->referer());
        } else {
          $this->Flash->error('There was a problem with your Contact form. Please,try again!');
        }
      } else {
        // user Failed to solve the captcha
        $this->Flash->error('Please,check the Google Recaptcha before proceeding.');
        $this->redirect($this->request->getSession()->read('Origin'));
      }
    }
  }
}

(recaptcha插件已在我的AppController的Initialize中加载。)

作为一个例子,在另一个控制器视图中的一种形式,我在其中调用主控制器的动作:

<?= $this->Form->create('client',['url' => ['controller' => 'clients','action' => 'contact']]); ?>
  <?= $this->Form->hidden('source',['value' => 'Product page']) ?>
  <?= $this->Form->control('first_name',['label' => 'First name:','required' => true]) ?>
  <?= $this->Form->control('last_name',['label' => 'Last name:','required' => true]) ?>
  <?= $this->Form->control('email',['label' => 'Email:','required' => true]) ?>
  <?= $this->Form->control('local_phone',['label' => 'Local phone:','maxlength' => 10,'required' => true]) ?>
  <?= $this->Form->control('comments',['label' => 'Comentarios:','rows' => 3]) ?>
  <?= $this->Recaptcha->display(); ?>
  <?= $this->Form->button('Send') ?>
<?= $this->Form->end(); ?>

解决方法

您可以在前端使用JavaScript来添加事件侦听器,以钩住表单提交按钮的点击。

在事件监听器中,将窗口的当前URL保存到浏览器中的sessionStorage。

然后将“提交点击”事件传递给默认操作。

此解决方案将在更改URL以添加表单字段内容之前存储URL。

对于将来的访问者,此解决方案涉及使用以下JavasCript概念,该概念已经在OP中使用,但可以单独进行研究:

  • 添加事件监听器
  • action ='click'
  • window.href
  • sessionStorage
  • 允许默认

您可以通过多种方式设置您正在监听的对象(表单提交按钮)。我通常给它一个ID并使用document.getElementById

指定元素

更多信息: