如何通过HTTP请求发送文件?Laravel测试上传JSON文件报Bad Request问题
问题原因
你当前的写法是直接将File::get()读取到的文件原始内容作为普通表单字段传递,而文件上传请求需要使用multipart/form-data编码格式,且文件字段需要对应上传文件实例而非内容字符串,这是触发400 Bad Request错误的核心原因。
正确实现方法
方式1:使用Laravel测试类的attach方法(更简便)
直接调用测试类自带的attach方法绑定本地文件,Laravel会自动构造符合要求的multipart/form-data请求:
$result = $this->post('admin/file/upload', [ 's_file_id' => $sFiles->id, 'type' => \App\Enums\File\Type::REP, ]) ->attach('main_file', $pathMainRNameFile, 'main.json') ->attach('sign_file', $pathSignRNameFile, 'sign.json');
参数说明:
- 第一个参数为后端接收的文件字段名
- 第二个参数为本地已存储的文件绝对路径
- 第三个参数为上传时的文件名,可自定义
方式2:手动构造UploadedFile实例
如果需要对文件属性做更精细的配置,可以先实例化UploadedFile再传入请求参数:
首先导入依赖类:
use Illuminate\Http\UploadedFile;
构造实例并发送请求:
// 构造主文件上传实例 $mainFile = new UploadedFile( $pathMainRNameFile, 'main.json', 'application/json', null, false // 测试结束后是否自动删除原文件,不需要自动删除则填false ); // 构造签名文件上传实例 $signFile = new UploadedFile( $pathSignRNameFile, 'sign.json', 'application/json', null, false ); // 发送请求 $result = $this->post('admin/file/upload', [ 's_file_id' => $sFiles->id, 'main_file' => $mainFile, 'sign_file' => $signFile, 'type' => \App\Enums\File\Type::REP, ]);
多进程场景额外注意事项
- 确保每个进程生成的文件路径唯一,避免跨进程文件读写冲突
- 确认当前进程对构造的文件路径有可读权限,避免文件读取失败导致参数异常
问题排查建议
如果修改后仍返回400错误,可按顺序排查:
- 检查后端路由对应的表单验证规则,确认是否对文件大小、后缀、MIME类型有额外限制
- 核对文件字段名拼写是否和后端接收逻辑一致(通常后端使用
$request->file('字段名')接收上传文件) - 打印请求错误信息
dd($result->json())查看具体的验证错误提示,定位问题字段
内容的提问来源于stack exchange,提问作者mohammad
相关产品推荐
相关产品推荐

