我最近迁移了我的代码,它在以前的服务器上完全正常,但在新的服务器上,POST请求不工作,但GET请求工作正常。此外,当我向同一服务器上的端点发送POST请求时,似乎也会出现此问题。当我向外部服务器发送POST请求时,代码运行良好。调试时,端点上不会接收通过(POST)发送的数据,而是通过cURL发送数据。
我正在使用此函数调用API端点:
function CallAPI($method = "GET", $url = "", $data = false, $credentials = "") {
try {
if (isset($url) && !empty($url)) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if (!empty($credentials)) {
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $credentials);
}
if ($method === "POST" || $method === "PUT") {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
} else if ($method === "GET") {
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
if ($response === false) {
throw new Exception("cURL error: " . curl_error($curl));
}
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
if ($httpCode < 200 || $httpCode >= 300) {
throw new Exception("HTTP error: " . $httpCode);
}
return $response;
} else {
return false;
}
} catch (Exception $e) {
// error_log("Error in CallAPI: " . $e->getMessage());
return false;
}
}
出于调试的目的,我创建了一个简单的脚本来输出发送过来的数据:
<?php
$response['status'] = "OK";
$data = !empty($_POST) ? $_POST : file_get_contents("php://input");
if (!empty($data)) {
$phpArray = json_decode($data, true);
$response['message'] = 'Data received successfully';
$response['data'] = $phpArray;
}
$response['status'] = 'Endpoint successfully reached.';
$response['method'] = $_SERVER['REQUEST_METHOD'];
$response['rawdata'] = $data;
echo json_encode($response);
exit;
?>
服务器详细信息
Previous Server:
CentOS 8
cPanel WHM
PHP 8.1
New Server:
CentOS 8
CyberPanel
PHP 8.1
我尝试过的:
1.检查PHP是否正确安装。
1.已检查cURL和扩展是否已正确安装。
1.尝试从其他服务器向新服务器发送POST请求。
EDIT经过进一步调试和调查,发现问题出在正在发送的数据上,这些数据在迁移之前、期间和之后都没有改变。以下是数据的示例:
$msg = "<h3>Hello ".ucwords($name).",</h3> We received your quotation request.<br/>Thank you for your interest in our services.<br/>Your quotation has been generated and attached to this email.<br/>We look forward to providing you with our services.<br/><hr/><small>Please note that a 60% upfront payment may be required before services are provided.</small><br/><small>Please note that this message is an automated response.</small><br/><p><p>You may need to download a PDF viewer program such as Adobe PDF Reader in order to view the attached document or you may simply download the document on your device and open the file using your browser.</p><strong><h5>Regards</h5>Support Team</strong><br/></p>";
$invoice = array(
"action" => "addQuote",
"type" => "document",
"ipaddress" => getIpAddress(),
"customer" => array(
"name" => $name,
"email" => $email,
"phone" => alphaNumeric($phone)
),
"products" => $cart,
"document" => array(
"name" => "quotation",
"date" => "",
"currency" => "",
"link" => ""
),
"mail" => array(
"subject" => $subject,
"to" => $email,
"bcc" => $info,
"text" => $msg,
"from" => $support,
"entity" => "Example Entity"
),
"sms" => array(
"to" => $phone,
"text" => "Hi ".ucwords($name).", Please find your quotation for requested services at $email. Thank you for your business.",
"token" => "f4eb27cea7255cea4d1ffabf593372e8"
),
"entity" => "5d14995453d10a56bd7c1d68"
);
$argv = json_encode(array("data" => $invoice));
$document = CallAPI("POST", "https://api.endpoint.com/", $argv);
print_r($document);
我开始使用简单的字符串数据来查看POST和cURL是否有效,并从服务器获得了响应。然后我还尝试注解掉$invoice
变量属性的一部分。我注意到,当我注解掉mail
属性中的msg
或sms
属性中的text
时,就像注解掉这两个属性中的任何一个一样,服务器将返回一个响应。
领悟:在记录print_r(strlen($argv));
时,我意识到只有当长度小于或等于1024时,我的代码才会运行并返回响应。
让我不禁要问:
json_encode
/json_decode
有问题。(我还尝试了htmlentities
和json_encode
的组合,但没有成功)
1.可以发布的数据有限制(我尝试在php.ini
中增加post_max_size
)
有没有其他人遇到过这种情况?有什么办法解决这个问题吗?
1条答案
按热度按时间2ekbmq321#
我终于找到了答案,在服务器上的区别是,在新的服务器上,当我用一个body POST请求时,客户端可能会包含“Expect:100-continue”标头。这个头告诉服务器在发送实际的请求体之前用“100 Continue”状态响应。
为了解决这个问题,我在CallAPI函数中包含了
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
。下面是我更新的CallAPI函数: