请求标头未与Zend Http一起发送

时间:2017-01-17 05:21:54

标签: php api zend-framework postman zend-http-client

我使用Zend \ Http \ Request和Zend \ Http \ Client

进行以下请求
        //Creating request and client objects
        $request = new Request();
        $client = new Client();

        //Preparing Request Object
        $request->setMethod('POST');
        $request->setUri('https://my.api.address.com/apiendpointurl1234');
        $request->getHeaders()->addHeaders(array(
            'cache-control' => 'no-cache',
            'content-type' => 'application/json',
            'client_secret' => 'asdfasdfasdfasdfasdf',
            'client_id' => 'asdfasdfasdfasdfasdf',
            'accept' => 'application/json',
            'authorization' => 'Basic MTIzNDoxMjM0',
        ));
        $request->getPost()->set(json_encode(array(
            'student_id' => '123456',
            'short_description' => 'this is short description',
            'description' => 'this is detailed description of the question',
        )));

        //Sending Request
        $response = $client->send($request);

        var_dump( $response->getBody() );

然而,响应出现此错误:

  

“error”:“headers:client_id required”

当我通过Postman戳API时,它工作正常。但是,当我从PHP应用程序调用它时,事实证明标头没有正确发送,这给出了上述错误。任何人都知道为什么没有发送标题?

6 个答案:

答案 0 :(得分:1)

尝试不使用addHeaders方法

// Setting multiple headers, overwriting any previous value
$client->setHeaders(array(
    'Host' => 'www.example.com',
    'Accept-encoding' => 'gzip,deflate',
    'X-Powered-By' => 'Zend Framework'));

也许你对客户端和请求对象感到困惑。

   $client = new Zend_Http_Client('http://example.org');
      $client->setHeaders(array(
        'Host' => 'www.example.com',
        'Accept-encoding' => 'gzip,deflate',
        'X-Powered-By' => 'Zend Framework'));
    $response = $client->request();

您可以在firebug中检查您的查询,例如检查服务器中发送的标头

答案 1 :(得分:1)

如果您想使用Request个对象,则可以使用setRequestdispatch方法:

use Zend\Http\Client;
use Zend\Http\Request;

$request = new Request();
$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);
$request->getHeaders()->addHeaders(array(
        'cache-control' => 'no-cache',
        'content-type' => 'application/json',
        'client_secret' => 'asdfasdfasdfasdfasdf',
        'client_id' => 'asdfasdfasdfasdfasdf',
        'accept' => 'application/json',
        'authorization' => 'Basic MTIzNDoxMjM0',
    ));

$client = new Client();

$client->setRequest($request);
$response = $client->dispatch();

答案 2 :(得分:1)

这对我有用:

//Creating request and client objects
$request = new Request();
$client = new Client();

//Preparing Request Object
$request->setMethod('POST');
$request->setUri('https://my.api.address.com/apiendpointurl1234');
$request->getHeaders()->addHeaders(array(
    'cache-control' => 'no-cache',
    'content-type' => 'application/json',
    'client_secret' => 'asdfasdfasdfasdfasdf',
    'client_id' => 'asdfasdfasdfasdfasdf',
    'accept' => 'application/json',
    'authorization' => 'Basic MTIzNDoxMjM0'
));

$client->setOptions(['strictredirects' => true]);

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));

//Sending Request
$response = $client->send($request);

echo ($response->getBody());

我的假设是,您的api会重定向到另一个网址并且标头会重置。您可以在Client.php的第943行看到

$this->resetParameters(false, false);

被调用。 这种情况在Postman中不会发生,因为Postman重复使用相同的标题进行重定向。

实际上,您只需添加

即可对此进行测试
$client->setOptions(['strictredirects' => true]);

应该允许在重定向之间保留标题。

PS:我尝试使用最新稳定版本的zend http上面的代码,它在“$ request-> getPost() - > set”行中给我一些错误。 无论如何,这不是问题的根源。

编辑: 我的第二个假设是api会查询“client_id”标题名称,这会导致错误,因为请求是由Zend \ Http \ Client发送的,它使用“Zend \ Http \ Client \ Adapter \ Socket”使每个标题的第一个字符为大写(第361行)。所以“Client_id”是实际发送的。 编辑Zend \ Http \ Client \ Adapter \ Socket“:

的第361行
 $v = ucfirst($k) . ": $v";

  $v = $k . ": $v";

并测试是否收到标题。

答案 3 :(得分:1)

我敢打赌,您需要在getHeaders之后立即将对Headers对象的引用存储在变量中,操作该对象,然后使用setHeaders更新Request对象上的标头。

$headers = $request->getHeaders();
$headers->addHeaders([ ... ... ]);
$request->setHeaders($headers);

答案 4 :(得分:1)

如果我没记错,因为我使用了Zend Framework for Requests,但getHeaders方法返回Headers对象,所以你需要使用和设置。

所以你的代码

 $request->getHeaders()->addHeaders(array(
     'cache-control' => 'no-cache',
     'content-type' => 'application/json',
     'client_secret' => 'asdfasdfasdfasdfasdf',
     'client_id' => 'asdfasdfasdfasdfasdf',
     'accept' => 'application/json',
     'authorization' => 'Basic MTIzNDoxMjM0',
));

需要成为

 $headers = $request->getHeaders();
 $headers->addHeaders(array(
     'cache-control' => 'no-cache',
     'content-type' => 'application/json',
     'client_secret' => 'asdfasdfasdfasdfasdf',
     'client_id' => 'asdfasdfasdfasdfasdf',
     'accept' => 'application/json',
     'authorization' => 'Basic MTIzNDoxMjM0',
 ));
 $request->setHeaders($headers);

如其他人之一所述:

在执行此操作之前,您需要将URI和方法设置为Post,因为您需要其他标题

$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);

最后,您需要在执行此操作之前设置帖子数据,因为它会影响您的标题,因为在您开始弄乱它们之前需要设置Content-Length标头

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));

所以你的脚本应该是

//Creating request and client objects
$request = new Request();
$client = new Client();
$request->setUri('https://my.api.address.com/apiendpointurl1234');

// Performing a POST request
$request->setMethod(Request::METHOD_POST);
$client->setOptions(['strictredirects' => true]);

$request->setContent(json_encode(array(
    'student_id' => '123456',
    'short_description' => 'this is short description',
    'description' => 'this is detailed description of the question',
)));
$headers = $request->getHeaders();
$headers->addHeaders(array(
    'cache-control' => 'no-cache',
    'content-type' => 'application/json',
    'client_secret' => 'asdfasdfasdfasdfasdf',
    'client_id' => 'asdfasdfasdfasdfasdf',
    'accept' => 'application/json',
    'authorization' => 'Basic MTIzNDoxMjM0',
));
$request->setHeaders($headers);

答案 5 :(得分:0)

事实证明Zend\Http\RequestZend\Http\Client库在进行调用时将下划线转换为连字符( - )。但是,cURL的行为略有不同。如果您以密钥值格式提供标题数组,则无法拨打电话,因为cURL会将client-id转换为client-id。但是,如果仅通过连接标头提供标准值数组,则调用成功。所以这是我的替代代码:

    // Get cURL resource
    $curl = curl_init();
    // Set some options - we are passing in a useragent too here
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => 'https://my.api.address.com/apiendpointurl1234',
        CURLOPT_POST => 1,
        CURLOPT_HTTPHEADER => [
            'client_id: ' . 'asdfasdfasdfasdf',
            'client_secret: ' . 'asdfasdfasdfasdfasdf',
            'Authorization: ' . 'Basic MTIzNDoxMjM0',
            'Content-Type: ' . 'application/json',
        ],
        CURLOPT_POSTFIELDS => [
            'student_id' => '111',
            'short_description' => 'this is the short description',
            'description' => 'this is the long description this is the long description this is the long description'
        ],
    ]);
    // Send the request & save response to $resp
    $response = curl_exec($curl);
    var_dump("Service call id is: " . $response);
    // Close request to clear up some resources
    curl_close($curl);

希望有所帮助。