返回

解决 wp_remote_post 发送短信 415 错误:详细指南

php

使用 wp_remote_post 发送短信时遇到的错误:问题解析与解决方案

当尝试使用 WordPress 的 wp_remote_post 函数发送短信时,开发者可能会遇到各种错误。 其中一种常见错误是 HTTP 状态码 415, 表示 “Unsupported Media Type(不支持的媒体类型)”。这通常指示发送请求中包含的 Content-Type 不被服务端接收。本文将分析此错误的原因,并提供相应的解决方案。

问题分析:415 错误的原因

在使用 wp_remote_post 发送数据时,默认的请求头不一定与短信 API 所要求的匹配。API 可能期望的是 application/json 或者 application/x-www-form-urlencoded 类型的数据,但是 wp_remote_post 在没有显式指定的情况下可能发送其他类型的 Content-Type,从而导致 415 错误。此外,API 对于 body 数据格式的要求,也会直接影响到请求的成功与否。例如,可能需要将数组数据转化为 URL 编码或者 JSON 格式,才能被 API 正确解析。

查看提供的结果,status_code 为 415,即服务端不支持客户端提交的媒体类型。因此,主要排查方向需要着重放在请求头的设置以及 body 数据的格式上。

解决方案 1:修改请求头 Content-Type

最常见的解决方法是手动设置 wp_remote_post 请求的 Content-Type 头。 如果短信 API 要求数据以 application/x-www-form-urlencoded 格式提交,就应这样设定。这种格式将数据编码为 key1=value1&key2=value2 的形式。 WordPress 默认的 POST 请求格式可能不是这种形式, 需要手动更改。

步骤:

  1. wp_remote_post 函数中添加 headers 参数,并设置 Content-Typeapplication/x-www-form-urlencoded
  2. 确保你的数据以键值对的形式放在 body 数组中。 WordPress 会自动处理成 URL 编码。

代码示例:

<?php

require_once 'wp-load.php';

$url = 'https://api.sprintsmsservice.com/api/SendSMS';

$response = wp_remote_post( $url, array(
    'method'      => 'POST',
    'timeout'     => 45,
    'redirection' => 5,
    'httpversion' => '1.0',
    'blocking'    => true,
    'headers'     => array(
        'Content-Type' => 'application/x-www-form-urlencoded',
    ),
    'body'        => array(
        'api_id'=>'xxxxxx',
        'api_password'=>'xxxxxx',
        'sms_type'=>'T',
        'encoding'=>'T',
        'sender_id'=>'ChonryOTP',
        'phonenumber'=>255714812XXX,
        'templateid'=>null,
        'textmessage'=>'Hello, This is a test message',
    ),
    'cookies'     => array(),
));

if ( is_wp_error( $response ) ) {
    $error_message = $response->get_error_message();
    echo "Something went wrong: $error_message";
} else {
    echo 'Response:<pre>';
    print_r( $response );
    echo '</pre>';
}

?>

安全建议:

  • api_idapi_password 等敏感信息存储在安全的位置,例如 WordPress 的设置 API 或者环境变量,不要直接写入代码中。
  • 限制请求来源,只允许服务器可以发送短信。
  • 定期更换 API 密钥。

解决方案 2:使用 JSON 数据格式

一些短信 API 可能要求使用 JSON 数据格式发送。 在这种情况下,你需要将 body 数据转换为 JSON 字符串,并相应地设置 Content-Type 头。

步骤:

  1. 设置 Content-Type 请求头为 application/json
  2. 使用 PHP 的 json_encode() 函数将数据数组转换为 JSON 字符串。
  3. 将转换后的 JSON 字符串赋值给 wp_remote_postbody 参数。

代码示例:

<?php

require_once 'wp-load.php';

$url = 'https://api.sprintsmsservice.com/api/SendSMS';
$data = array(
    'api_id'=>'xxxxxx',
    'api_password'=>'xxxxxx',
    'sms_type'=>'T',
    'encoding'=>'T',
    'sender_id'=>'ChonryOTP',
    'phonenumber'=>255714812XXX,
    'templateid'=>null,
    'textmessage'=>'Hello, This is a test message',
);

$response = wp_remote_post( $url, array(
    'method'      => 'POST',
    'timeout'     => 45,
    'redirection' => 5,
    'httpversion' => '1.0',
    'blocking'    => true,
    'headers'     => array(
        'Content-Type' => 'application/json',
    ),
    'body'        => json_encode($data),
    'cookies'     => array(),
));


if ( is_wp_error( $response ) ) {
    $error_message = $response->get_error_message();
    echo "Something went wrong: $error_message";
} else {
    echo 'Response:<pre>';
    print_r( $response );
    echo '</pre>';
}
?>

注意事项:

  • 仔细阅读短信 API 的文档,以确定其具体的要求的数据格式和请求头设置。
  • 处理响应结果,确保可以捕获成功或失败,并采取必要的行动,例如记录日志或者提示用户。
  • 可以添加额外的调试措施,比如在请求发送前打印请求头和 body,帮助快速诊断问题。
  • wp_remote_post 有时可能会受到 SSL 证书验证问题的影响。 可以添加sslverify参数并设置为false 来临时禁用验证 (仅供测试和调试,不推荐在生产环境中使用)。 正确的处理方式是在你的服务器上配置好有效的SSL证书。
 'sslverify' => false

重要提示: 如果尝试上述解决方案后,问题仍然存在,建议仔细检查API 文档, 确定正确的 API 端点、参数以及任何可能需要传递的额外请求头。 联系短信服务商的技术支持也可以得到额外的帮助。