PHP脚本调用HTTP Post接口返回404,Node.js调用正常
PHP调用GraphQL接口返回404,Node.js却正常的问题分析
同一GraphQL接口部署在Azure Front Door后方的Azure App Service上,Node.js脚本调用能正常返回200状态码及预期结果,但PHP脚本调用返回404,且App Service日志中观测到404错误。API端点已替换为占位符,但两种脚本使用的端点完全一致。
PHP脚本
$apiKey = "someAPIKey"; $accountId = "someAccountId"; $txRequest = createTransaction(); // 返回JSON格式数据 $baseUri = "https://someapiendpoint.com/graphql"; $headers = [ "Accept: application/json", "X-API-KEY: $apiKey", "Account: $accountId", ]; echo $txRequest; $ch = curl_init($baseUri); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $txRequest); $response = curl_exec($ch); curl_close($ch); if ($response === FALSE) { echo "cUrl error (#%d): %s<br>\n"; } echo $response;
PHP请求日志
* Connected to someapiendpoint.com (xxx:xxx:xxx:xxx) port 443 (#0) * ALPN: offers h2 * ALPN: offers http/1.1 * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256 * ALPN: server accepted h2 * Server certificate: * subject: CN=someapiendpoint.com * start date: Jun 11 00:00:00 2023 GMT * expire date: Dec 11 23:59:59 2023 GMT * subjectAltName: host "someapiendpoint.com" matched cert's "someapiendpoint.com" * issuer: C=US; O=DigiCert, Inc.; CN=GeoTrust Global TLS RSA4096 SHA256 2022 CA1 * SSL certificate verify result: self-signed certificate in certificate chain (19), continuing anyway. * Using HTTP2, server supports multiplexing * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * h2h3 [:method: POST] * h2h3 [:path: /graphql] * h2h3 [:scheme: https] * h2h3 [:authority: someapiendpoint.com] * h2h3 [accept: application/json] * h2h3 [x-api-key: someAPIKey] * h2h3 [account: someAccountId] * h2h3 [content-length: 1187] * h2h3 [content-type: application/x-www-form-urlencoded] * Using Stream ID: 1 (easy handle 0x264ace0f260) > POST /graphql HTTP/2 Host: someapiendpoint.com accept: application/json x-api-key: someAPIKey account: someAccountId content-length: 1187 content-type: application/x-www-form-urlencoded * Connection state changed (MAX_CONCURRENT_STREAMS == 128)! * We are completely uploaded and fine < HTTP/2 404 < date: Thu, 05 Oct 2023 22:43:53 GMT < content-length: 0 < x-robots-tag: noindex,nofollow < x-correlation-id: 000000000000000000000000 < x-azure-ref: 0000000000000000000000000000000000000000 < x-cache: CONFIG_NOCACHE < * Connection #0 to host someapiendpoint.com left intact
Node.js脚本
const response = await axios.post( 'https://someapiendpoint.com/graphql', txRequest, // 返回JSON格式数据 { headers: { Accept: 'application/json', 'X-API-KEY': 'someAPIKey', Account: 'someAccountId', }, } ); console.log(response.data);
问题原因及修复方案
从PHP请求日志可看出,请求的Content-Type被自动设为application/x-www-form-urlencoded,但GraphQL接口通常要求接收application/json格式的请求体。而Node.js的axios在发送JSON数据时,会自动添加Content-Type: application/json请求头,同时正确序列化请求体,因此后端能正常解析处理。
修复步骤:
- 在PHP请求头中添加
Content-Type: application/json; - 确保
$txRequest是有效的JSON字符串(若createTransaction()返回的是数组,需用json_encode()转换)。
修改后的PHP脚本关键部分:
// 确保请求体为JSON字符串(如果createTransaction返回数组) $txRequest = json_encode(createTransaction()); $headers = [ "Accept: application/json", "Content-Type: application/json", // 新增该请求头 "X-API-KEY: $apiKey", "Account: $accountId", ];
修改后PHP发送的请求格式将与Node.js一致,后端可正常处理并返回预期结果。
内容的提问来源于stack exchange,提问作者Derek J.
相关产品推荐
相关产品推荐

