gpt4 book ai didi

PHP cURL POST 返回 415 - 不支持的媒体类型

转载 作者:可可西里 更新时间:2023-11-01 13:33:56 27 4
gpt4 key购买 nike

我有一个简单的 PHP 脚本,它通过 cURL 发送一个 HTTP POST 请求,并期望一个 json 字符串作为响应(很想为此使用现有的库,如 pecl_http/HTTPRequest,但不能)。调用始终失败并出现 415 错误 - 不支持的媒体类型。我想我没有正确配置 cURL,但经过大量搜索后,我无法找出我做错了什么。这是一些代码:

class URLRequest
{
public $url;
public $headers;
public $params;
public $body;
public $expectedFormat;
public $method;

public function URLRequest($aUrl, array $aHeaders, array $aParams, $aFormat = "json", $isPost = false, $aBody = "+")
{
$this->url = $aUrl;
$this->headers = $aHeaders;
$this->params = $aParams;
$this->expectedFormat = $aFormat;
$this->method = ($isPost ? "POST" : "GET");
$this->body = $aBody;

}

public function exec()
{

$queryStr = "?";
foreach($this->params as $key=>$val)
$queryStr .= $key . "=" . $val . "&";

//trim the last '&'
$queryStr = rtrim($queryStr, "&");

$url = $this->url . $queryStr;

$request = curl_init();
curl_setopt($request, CURLOPT_URL, $url);
curl_setopt($request, CURLOPT_HEADER, 1);
curl_setopt($request, CURLOPT_HTTPHEADER, $this->headers);
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
//curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);

if($this->method == "POST")
{
curl_setopt($request, CURLOPT_POST, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $this->body);

//this prevents an additions code 100 from getting returned
//found it in some forum - seems kind of hacky
curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:"));
}

$response = curl_exec($request);
curl_close($request);

preg_match("%(?<=HTTP/[0-9]\.[0-9] )[0-9]+%", $response, $code);

$resp = "";
if($this->expectedFormat == "json")
{
//parse response
}
elseif($this->expectedFormat == "xml")
{
//parse response
}

return $resp;

}
}


$url = "http://mydomain.com/myrestcall";

$query = array( "arg_1" => "test001",
"arg_2" => "test002",
"arg_3" => "test003");

$headers = array( "Accept-Encoding" => "gzip",
"Content-Type" => "application/json",
"Accept" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");

$body = array( "body_arg_1" => "test021",
"body_arg_2" => array("test022", "test023"),
"body_arg_3" => "test024");


$request = new URLRequest($url, $headers, $query, "json", true, $body);

$response = $request->exec();

...以及响应:

HTTP/1.1 415 Unsupported Media Type
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Content-Type: text/html;charset=utf-8
Content-Length: 1047
Date: Mon, 18 Jun 2012 16:30:44 GMT

<html><head><title>JBoss Web/2.1.3.GA - Error report</title></head><body><h1>HTTP Status 415 - </h1><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().</u></p><h3>JBoss Web/2.1.3.GA</h3></body></html>

有什么见解或想法吗?

提前致谢!

最佳答案

问题解决了!这是问题所在:

发送标题的关联数组不适用于 cURL。有几个论坛散布在展示使用标题关联数组的示例。不要这样做!

正确的方法(也散布在互联网上,但我太密集以至于没有注意到)是将您的 header 键/值对构造为字符串,并传递一个标准数组设置 CURLOPT_HTTPHEADER 选项时使用这些字符串。

总而言之,

错误:

$headers = array(    "Accept-Encoding" =>    "gzip",
"Content-Type" => "application/json",
"custom_header_1" => "test011",
"custom_header_2" => "test012",
"custom_header_3" => "test013");

右:

$headers = array(    "Accept-Encoding: gzip",
"Content-Type: application/json",
"custom_header_1: test011",
"custom_header_2: test012",
"custom_header_3: test013");

我希望这对以后的其他一些高尚的傻瓜有用,以免他们像我一样浪费那么多时间进行调试。

如果非要我猜的话,我会假设相同的规则也适用于 POST 正文键/值对,这就是为什么 @drew010 关于使用 http_build_query()json_encode() 来字符串化您的消息正文也是一个好主意。

感谢大家提出非常有用的意见,感谢您抽出宝贵的时间和考虑。最后,并排比较 http 流量(通过 Wireshark 捕获)揭示了这个问题。

谢谢!

关于PHP cURL POST 返回 415 - 不支持的媒体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11087872/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com