You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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令牌再发起请求:
  1. 先访问站点获取包含CSRF令牌的Cookie:
curl -c cookies.txt http://file.localhost
  1. 从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 15:42:43