Windows下用Curl向Yii2控制器上传文件报400错误求助
解决Yii2控制器接收Curl文件上传时的Bad Request (#400)错误
问题场景
使用Windows命令行的Curl工具向Yii2控制器上传文件,执行的Curl命令如下:
curl -X POST -F "file=@G:\file.txt" http://file.localhost/file-siakadbeta/upload
对应的Yii2控制器代码为:
class FileSiakadbetaController extends Controller { public function actionUpload() { if ($_FILES && isset($_FILES['file'])) { $target_dir = "uploads/"; // 替换为目标上传目录 $target_file = $target_dir . basename($_FILES['file']['name']); // 检查文件是否已存在 if (file_exists($target_file)) { return "File already exists."; } else { // 将上传文件移动到目标目录 if (move_uploaded_file($_FILES['file']['tmp_name'], $target_file)) { return "File uploaded successfully."; } else { return "File upload failed."; } } } else { return "No file uploaded."; } } }
请求返回错误:
Bad Request (#400)
该Curl命令在普通PHP代码中可正常完成上传,需解决此问题。
解决方法
- 关闭目标动作的CSRF验证
Yii2默认开启CSRF防护机制,POST请求必须携带合法的CSRF令牌才能通过验证。可以在控制器中仅关闭upload动作的CSRF验证:
class FileSiakadbetaController extends Controller { public function behaviors() { $behaviors = parent::behaviors(); // 配置csrfFilter,排除upload动作 $behaviors['csrfFilter'] = [ 'class' => \yii\filters\CsrfFilter::class, 'except' => ['upload'], ]; return $behaviors; } public function actionUpload() { // 原上传代码... } }
若仅为测试环境,也可全局关闭控制器的CSRF验证(生产环境不推荐):
class FileSiakadbetaController extends Controller { public $enableCsrfValidation = false; public function actionUpload() { // 原上传代码... } }
- 在Curl请求中携带CSRF令牌
若要保留CSRF防护,需先获取合法的CSRF令牌再发起请求:
- 先访问站点获取包含CSRF令牌的Cookie:
curl -c cookies.txt http://file.localhost
- 从
cookies.txt中提取_csrf的值,或从站点页面源码的<meta name="csrf-token" content="xxx">标签中获取令牌内容,然后在上传命令中携带:
curl -X POST -b cookies.txt -F "file=@G:\file.txt" -F "_csrf=获取到的CSRF令牌值" http://file.localhost/file-siakadbeta/upload
验证路由配置正确性
确认file-siakadbeta/upload路由能正确映射到FileSiakadbetaController的actionUpload方法。可通过访问http://file.localhost/index.php?r=file-siakadbeta/upload测试路由是否有效,若返回正常页面则路由配置无误。检查上传目录权限与存在性
确保控制器中指定的uploads/目录存在,且PHP进程拥有该目录的写入权限。可在上传代码中添加目录创建逻辑:
$target_dir = "uploads/"; if (!file_exists($target_dir)) { mkdir($target_dir, 0755, true); // 递归创建目录 }
内容的提问来源于stack exchange,提问作者eniac05
相关产品推荐
相关产品推荐

