Yii2框架视频上传出现Bad Request (#400)错误,寻求技术支持
Hey there! Let's break down and fix the issues you're facing with your Yii2 video upload feature. That 400 error usually ties to CSRF validation failures, but there are a few other bugs in your code contributing to the problem too. Here's how to fix everything step by step:
1. Fix the CSRF Validation Issue
Yii2's CSRF protection is enabled by default, but multipart/form-data forms can sometimes have issues if the CSRF token isn't properly included. Let's reinforce this:
- Check your rendered form (view source in your browser) to ensure there's a hidden CSRF field like:
<input type="hidden" name="_csrf" value="..."> - If it's missing, explicitly enable CSRF in your ActiveForm configuration:
<?php $form = ActiveForm::begin([ 'options'=>['enctype'=>'multipart/form-data'], 'enableCsrfValidation' => true, // Add this line to enforce CSRF ]); ?> - Double-check your controller doesn't have
public $enableCsrfValidation = false;(remove this line if it exists—disabling CSRF is risky here).
2. Correct Model Validation Rules
Your model has a critical typo and incorrect rule setup that's breaking validation:
- You defined a rule for
videof, but your form uses the fieldvideo—this mismatch will cause validation to fail silently. - The
maxSizevalue is a string ('2048000') but should be an integer (2048000, which equals 2MB). - Update your
rules()method like this:public function rules() { return [ [['title'], 'required'], // Remove 'video' here—we'll enforce it in the file rule [['video'], 'file', 'extensions' => 'mp4', 'maxSize' => 2048000, 'required' => true, // Ensures a video file is uploaded 'tooBig' => 'Video size cannot exceed 2MB.', // Optional: Custom error message ], [['created_by', 'updated_by'], 'integer'], [['created_at', 'updated_at'], 'safe'], [['video', 'title', 'date'], 'string', 'max' => 255], ]; }
3. Fix Upload Path & Directory Logic
Using relative paths like ../themes/... is unreliable—use Yii's aliases to get absolute paths, and ensure the upload directory exists:
- In your controller, replace the hardcoded path with an alias (adjust
@appto match your project structure, e.g.,@frontendif using the advanced template):// Get absolute path using Yii alias $uploadDir = Yii::getAlias('@app/themes/light/images/video/'); // Create directory if it doesn't exist if (!file_exists($uploadDir)) { mkdir($uploadDir, 0777, true); // 0777 permissions (adjust based on your server's security needs) } // Save the file to the server $model->video->saveAs($uploadDir . $videoName . '.' . $model->video->extension);
4. Improve Controller Upload Logic
Your current controller skips model validation before saving, which can lead to silent failures. Update the actionCreate() method to validate first:
public function actionCreate() { $model = new Videos(); if ($model->load(Yii::$app->request->post())) { // Get the uploaded file instance $model->video = UploadedFile::getInstance($model,'video'); // Validate the model first to catch errors early if ($model->validate()) { $videoName = "video_".rand(); $uploadDir = Yii::getAlias('@app/themes/light/images/video/'); if (!file_exists($uploadDir)) { mkdir($uploadDir, 0777, true); } // Save the file to the server $model->video->saveAs($uploadDir . $videoName . '.' . $model->video->extension); // Update model with the relative path for database storage $model->video = 'themes/light/images/video/'.$videoName.'.'.$model->video->extension; $model->created_by = Yii::$app->user->identity->id; // Save model without re-validating (we already did it) $model->save(false); return $this->redirect(['view', 'id' => $model->id]); } } return $this->render('create', [ 'model' => $model, ]); }
Final Checks
- Ensure your server has write permissions for the
themes/light/images/video/directory. - Test the upload again—you should no longer see the 400 error, and valid videos will save correctly to your server and database.
内容的提问来源于stack exchange,提问作者Kedar Shivshette

