如何防止在Yii2中提交多个表单?

时间:2016-09-04 22:36:09

标签: javascript jquery yii2

为了使用以下代码处理表单(仅用于测试):

$(document).on("beforeSubmit", "#test-form", function (event, messages) {
    $(this).find(':submit').attr('disabled', true);
    console.log('Test new form');
    return false;
});

但是,尽管我将提交按钮设置为非活动状态,但我们可以在控制台中看到,当我快速单击按钮时,该表单至少提交两次。作为临时修复,编写了以下代码:

$(document).on("beforeValidate", "form", function(event, messages, deferreds) {
    $(this).find(':submit').attr('disabled', true);
    console.log('BEFORE VALIDATE TEST');
}).on("afterValidate", "form", function(event, messages, errorAttributes) {
    console.log('AFTER VALIDATE TEST');
    if (errorAttributes.length > 0) {
        $(this).find(':submit').attr('disabled', false);
    }
});
$(document).on("beforeSubmit", "#test-form", function (event, messages) {
    console.log('Test new form');
    return false;
});

但不确定这是一个好的决定。如何解决这个问题?
提前致谢!

1 个答案:

答案 0 :(得分:5)

一种解决方案是使用JavaScript禁用该按钮。但是由于浏览器问题或者用户可能在他的浏览器中禁用了JavaScript,所以这种情况一直都不高效。

另一种解决方案是每次在服务器端检查表单是否已使用会话中保存的令牌提交。

以下代码可在https://github.com/yiisoft/yii2/issues/10498中找到:

<强>模型

public function getHiddenFormTokenField() {
    $token = \Yii::$app->getSecurity()->generateRandomString();
    $token = str_replace('+', '.', base64_encode($token));

    \Yii::$app->session->set(\Yii::$app->params['form_token_param'], $token);;
    return Html::hiddenInput(\Yii::$app->params['form_token_param'], $token);
}

&#34;表单提交时,名为&#39; beforeAction&#39;在控制器类中比较发送的令牌与会话中的值。每次执行操作后都会清理会话。如果值不同,则抛出异常。&#34;

<强>控制器

public function beforeAction($action) {
    $formTokenName = \Yii::$app->params['form_token_param'];

    if ($formTokenValue = \Yii::$app->request->post($formTokenName)) {
        $sessionTokenValue = \Yii::$app->session->get($formTokenName);

        if ($formTokenValue != $sessionTokenValue ) {
            throw new \yii\web\HttpException(400, 'The form token could not be verified.');
        }

        \Yii::$app->session->remove($formTokenName);
    }

    return parent::beforeAction($action);
}