YII 2.0 Bad Request (#400)


post提交表單的時候出現在這個錯誤是因爲Yii2.0默認開啓了_crsf的驗證

可以在控制器裏局部禁用
public $enableCsrfValidation = false ->覆蓋父類的屬性

也可以在配置文件中全局禁用
 'components' => [
        'request' => [
            /**
            /*!!! insert a secret key in the following (if it is empty) - this is required by    
            /*cookie validation
            /**
            'cookieValidationKey' => '83r5HbITBiMfmiYPOZFdL-raVp4O1VV4',
            'enableCookieValidation' => false,
            'enableCsrfValidation' => false,
        ]

當然,我們並不建意這樣做。

如果是用ActiveForm生成的表單,用傳統的POST提交這裏是不會有問題的。

我們可以來看看YII2.0的源碼。

\yii\widgets\ActiveForm
這個類裏面有一個run方法
/**
     * Runs the widget.
     * This registers the necessary javascript code and renders the form close tag.
     * @throws InvalidCallException if `beginField()` and `endField()` calls are not matching
     */
    public function run()
    {
        if (!empty($this->_fields)) {
            throw new InvalidCallException('Each beginField() should have a matching endField() call.');
        }

        $content = ob_get_clean();
        echo Html::beginForm($this->action, $this->method, $this->options);
        echo $content;

        if ($this->enableClientScript) {
            $id = $this->options['id'];
            $options = Json::htmlEncode($this->getClientOptions());
            $attributes = Json::htmlEncode($this->attributes);
            $view = $this->getView();
            ActiveFormAsset::register($view);
            $view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);");
        }

        echo Html::endForm();
    }
可以看到 echo Html::beginForm($this->action, $this->method, $this->options);這樣一句。
在Html::beginForm()這個方法裏面
if ($csrf && $request->enableCsrfValidation && strcasecmp($method, 'post') === 0) {
    $hiddenInputs[] = static::hiddenInput($request->csrfParam, $request->getCsrfToken());
}
這樣一段代碼就是在表單寫入了一個hide input加入了_csrf
如果不是用的ActiveForm則需要手動加入:
<input type="hidden" name="<?php echo Yii::$app->request->csrfParam;?>" value="<?php echo Yii::$app->request->getCsrfToken();?>">

如果是ajax post則要在data後面也帶上這個參數

YII2.0 標準寫法

<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <?= Html::csrfMetaTags() ?>
    <title><?= Html::encode($this->title) ?></title>
    <?php $this->head() ?>
</head>
表單
<?php $form = ActiveForm::begin(['id' => 'login-form']); ?>
<?php ActiveForm::end(); ?>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章