Laravel使用Curl发送POST mutation请求时base64图片无法识别如何解决
Laravel 调用x-www-form-urlencoded格式接口时base64图片无法识别的解决方案
问题根因
你的代码存在两个核心问题,导致接口无法正常解析图片:
- 未对请求参数做标准URL编码:官方示例用
--data-urlencode参数自动对参数特殊字符做编码,你直接拼接裸字符串传给POST字段,base64包含的+、/、=等特殊字符会在传输中被转义损坏,接口拿到的base64串是残缺的,解码后不是合法图片格式。 - 手动拼接多层嵌套的GraphQL语句、内嵌JSON结构极易出现转义错误,引号、特殊字符处理不当会直接破坏参数结构。
修复方案
方案1:修正原生cURL写法
核心调整点:
- 用数组格式传递POST参数,cURL会自动完成x-www-form-urlencoded格式编码,效果和官方示例的
--data-urlencode完全一致 - 用
json_encode生成内嵌的personInfo JSON串,避免手动拼接转义出错 - 规范cURL配置,去掉不合理的无限超时设置,保证请求头格式和官方示例一致
$curl = curl_init(); $name = request()->name; $image64 = request()->input('image64'); // 自动生成personInfo的JSON字符串,避免手动转义错误 $personInfo = json_encode(['name' => $name], JSON_UNESCAPED_UNICODE); // 构造完整GraphQL mutation语句 $graphqlQuery = <<<GQL mutation { createProfile(profileData: { personInfo: "{$personInfo}", samplesData: {image: "{$image64}"} }) { ok, profile {id} } } GQL; curl_setopt_array($curl, array( CURLOPT_URL => 'https://facemachine.3divi.com/api/v2/', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => 'charset=utf-8', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_POST => true, // 传数组格式参数,cURL自动做表单编码 CURLOPT_POSTFIELDS => [ 'query' => $graphqlQuery ], CURLOPT_HTTPHEADER => array( 'token: 242903fb-7e53-xxx-xxxx-xxxxx', ), )); $response = curl_exec($curl); $curlError = curl_error($curl); curl_close($curl); if ($curlError) { return response()->json(['curl_error' => $curlError], 500); } return json_decode($response);
方案2:使用Laravel自带HTTP客户端(推荐)
Laravel内置的HTTP客户端已经封装了表单编码、错误处理等逻辑,不需要手动配置cURL参数,代码更简洁易维护:
use Illuminate\Support\Facades\Http; $name = request()->name; $image64 = request()->input('image64'); $personInfo = json_encode(['name' => $name], JSON_UNESCAPED_UNICODE); $response = Http::withHeaders([ 'token' => '242903fb-7e53-xxx-xxxx-xxxxx' ])->asForm() // 自动设置表单请求头,自动编码参数 ->post('https://facemachine.3divi.com/api/v2/', [ 'query' => <<<GQL mutation { createProfile(profileData: { personInfo: "{$personInfo}", samplesData: {image: "{$image64}"} }) { ok, profile {id} } } GQL ]); return $response->json();
额外排查点
如果调整编码后仍然报错,优先检查传入的base64参数合法性:
- 确认base64串没有携带
data:image/png;base64,这类文件头前缀,这类前缀需要截断后再传给接口 - 可以将接收到的base64串解码保存为本地图片文件,测试文件是否能正常打开,排除前端上传的图片本身损坏、base64编码错误的问题
内容的提问来源于stack exchange,提问作者Muhammad Rizky Pangestu
相关产品推荐
相关产品推荐

