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

PHP向API传输数组时触发400错误,请求排查问题根源

问题:Gravity Form数据同步CRM时API返回400错误

错误信息

{"error":{"httpStatusCode":400,"message":"Expected end of string, but instead reached end of data. Path: $.name | LineNumber: 2 | BytePositionInLine: 7.","messageType":"Error"},"response":null}

相关代码

add_filter( 'gform_after_submission', 'registrazone', 10, 2 );

function registrazone ( $entry, $form) {
     #FIXME: Hardcoded url
$url2 = 'https://gogogogo.com/api/load';

#Assumption: The params below have already been verified.
$topup_data2 = array("accept"        =>      "text/plain",
                     "token"         =>      $token);
                    

#JSON encode the params
$topup_str2   = json_encode($topup_data2);

#Curl init
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, $url2);
curl_setopt($ch2, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: '.strlen($topup_str2)
    )
);  

$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$note = "Contatto da pagina " . $actual_link;
$valid_cellulare_b = rgar( $entry, '7' );

#I use JSON_NUMERIC_CHECK but thinks that error is for not "" so use strval
$valid_cellulare_a = strval( $valid_cellulare_b ); 

$payload = json_encode( array( 'nome' => rgar( $entry, '3.3' ),
                                'cellulare'=>$valid_cellulare_a,
                                'email' => rgar( $entry, '5' ), 
                                'nota' => $note,
                                'cognome' => rgar( $entry, '3.6' ),                                                               
                                'provinciaDomicilio' => rgar( $entry, '9' ),
                            ), 
                            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
                      );
echo "<pre>$payload</pre>";
curl_setopt($ch2, CURLOPT_POSTFIELDS, $payload);
# Return response instead of printing.
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
# Send request.
$result2 = curl_exec($ch2);
curl_close($ch2);
# Print response.
echo "<pre>$result2</pre>";

}

生成的Payload

{
    "nome": "Joan",
    "cellulare": "349XXXXXXX",
    "email": "info@XXXXXX.com",
    "nota": "Contact from page https://gogogogogogo.com",
    "cognome": "Trello",
    "provinciaDomicilio": "GG"
}

问题排查与修复方案

核心错误原因

  1. 字段名不匹配:API明确提示期望$.name字段,但你发送的是nome(意大利语"名字"),字段名不匹配导致API无法正确解析数据。
  2. Content-Length设置错误:你手动设置的Content-Length是$topup_str2的长度,但实际POST的是$payload,两者长度不一致,服务器读取数据时提前结束,触发JSON解析错误。
  3. Token传递方式错误:你将授权Token放在了未使用的$topup_data2数组中,未正确传递到API请求里,可能导致授权验证问题(虽然当前错误未直接体现,但属于潜在问题)。

修复后的代码示例

add_filter( 'gform_after_submission', 'registrazone', 10, 2 );

function registrazone ( $entry, $form) {
    // FIXME: Hardcoded url
    $url2 = 'https://gogogogo.com/api/load';

    // 假设$token已通过授权接口正确获取
    $token = 'your_valid_token_here';

    // Curl初始化
    $ch2 = curl_init();
    curl_setopt($ch2, CURLOPT_URL, $url2);
    // 设置正确的请求头:包含授权Token,Content-Type为JSON
    curl_setopt($ch2, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        "Authorization: Bearer $token" // 标准Bearer Token授权方式
    ));  

    $actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    $note = "Contatto da pagina " . $actual_link;
    $valid_cellulare_b = rgar( $entry, '7' );
    $valid_cellulare_a = strval( $valid_cellulare_b ); 

    // 修正字段名:将nome改为API期望的name,其他字段需对照API文档确认
    $payload = json_encode( array( 
        'name' => rgar( $entry, '3.3' ),
        'cellulare' => $valid_cellulare_a,
        'email' => rgar( $entry, '5' ), 
        'nota' => $note,
        'lastName' => rgar( $entry, '3.6' ), // 假设cognome对应API的lastName,需确认文档
        'provinciaDomicilio' => rgar( $entry, '9' ),
    ), JSON_UNESCAPED_SLASHES ); // 生产环境可去掉JSON_PRETTY_PRINT减少数据体积

    // 调试用,生产环境建议注释
    echo "<pre>$payload</pre>";

    curl_setopt($ch2, CURLOPT_POSTFIELDS, $payload);
    curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch2, CURLOPT_POST, 1); // 显式设置POST请求

    // 执行请求并捕获curl错误
    $result2 = curl_exec($ch2);
    if(curl_errno($ch2)){
        echo 'Curl错误: ' . curl_error($ch2);
    }
    curl_close($ch2);

    echo "<pre>$result2</pre>";
}

关键修复点

  1. 字段名对齐:严格按照CRM API文档的字段名传递数据,比如将nome改为name,cognome需确认对应API的字段名(如lastName)。
  2. 移除手动Content-Length:让cURL自动计算并设置正确的Content-Length,避免长度不匹配问题。
  3. 规范Token传递:将Token放在HTTP请求头的Authorization字段中,使用标准的Bearer {token}格式(除非API明确要求放在POST数据中)。
  4. 优化JSON编码:生产环境去掉JSON_PRETTY_PRINT,减少请求数据体积,提升传输效率。

内容的提问来源于stack exchange,提问作者Giandomenico Viglione

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:30:50