0

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

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

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

然后我搜索了一些解决方案(在谷歌和堆栈溢出中),在一个类似的问题中,有一个答案是“将您当前的 url 保存到会话中并加载它以进行重定向”,这是有道理的。但是,当我尝试保存它时,我发现会话在进程启动后被保存所以我的会话在跳转到主要操作之后保存 url,而不是在提交表单之前。

我尝试将会话保存在 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(); ?>
4

1 回答 1

0

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

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

然后让提交点击事件传递给默认动作。

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

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

  • 添加事件监听器
  • 动作 = '点击'
  • 窗口.href
  • 会话存储
  • 允许默认

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

更多信息:

于 2020-08-29T02:58:12.573 回答