如何修复PHP中cURL上传文件到Pangea的InvalidBodyError问题
解决PHP cURL调用Pangea文件扫描API的InvalidBodyError问题
我有一段官方文档中的curl命令:
curl -sSLX POST 'https://file-scan.aws.us.pangea.cloud/v1/scan' \ -H 'Authorization: Bearer my-token-goes here' \ -H 'Content-Type: multipart/form-data' \ -F 'request={"transfer_method":"multipart"};type=application/json' \ -F 'upload=@AnnBall.png;type=application/octet-stream'
将其改写为PHP cURL代码用于文件上传:
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://file-scan.aws.us.pangea.cloud/v1/scan'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer my-token-goes-here', 'Content-Type: multipart/form-data', ]); curl_setopt($ch, CURLOPT_POSTFIELDS, [ 'request' => '{"transfer_method":"multipart"}', 'upload' => new CURLFile('AnnBall.png', 'application/octet-stream'), ]); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); echo $response = curl_exec($ch); curl_close($ch); ?>
执行后出现以下错误:
{"request_id":"prq_nxj6w7ws5ussjsniphkzk7i3pqlf5peu","request_time":"2024-04-25T17:15:00.638627Z","response_time":"2024-04-25T17:15:01.722276Z","status":"InvalidBodyError","summary":"Failed to read request body","result":null}
问题原因及解决方法
核心问题
- 手动设置Content-Type导致头部缺失boundary:PHP处理数组格式的
CURLOPT_POSTFIELDS时,会自动生成带boundary分隔符的multipart/form-data头部,手动设置该字段会覆盖正确头部,导致服务端无法解析表单。 - request字段未指定JSON类型:原始curl命令中
request字段明确标注了type=application/json,但PHP默认会把字符串字段以text/plain类型发送,服务端无法识别该字段为JSON格式。
修正后的代码(PHP 8.1+推荐)
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://file-scan.aws.us.pangea.cloud/v1/scan'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer my-token-goes-here', // 移除手动设置的Content-Type,让PHP自动生成带boundary的头部 ]); curl_setopt($ch, CURLOPT_POSTFIELDS, [ // 用CURLStringFile指定request字段的内容类型为application/json 'request' => new CURLStringFile('{"transfer_method":"multipart"}', '', 'application/json'), 'upload' => new CURLFile('AnnBall.png', 'application/octet-stream'), ]); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $response = curl_exec($ch); echo $response; curl_close($ch); ?>
兼容PHP <8.1的方案
如果PHP版本低于8.1,没有CURLStringFile,可以用数组指定字段的内容和类型:
<?php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://file-scan.aws.us.pangea.cloud/v1/scan'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer my-token-goes-here', ]); $postFields = [ 'request' => [ 'value' => '{"transfer_method":"multipart"}', 'type' => 'application/json', ], 'upload' => new CURLFile('AnnBall.png', 'application/octet-stream'), ]; curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $response = curl_exec($ch); echo $response; curl_close($ch); ?>
内容的提问来源于stack exchange,提问作者Nancy Moore
相关产品推荐
相关产品推荐

