简体   繁体   English

cURL POST 请求有效,Guzzle 6 无效

[英]cURL POST request works, Guzzle 6 does not

Context:语境:

I've been working on figuring out how to make this work for a while, and I simply don't understand why Guzzle isn't working for this particular request.一段时间以来,我一直在研究如何使这项工作发挥作用,但我根本不明白为什么 Guzzle 不能满足这个特定的要求。 The same initialization and request structure works in some basic unit tests I have, but when it comes to API to API communication, Guzzle just is not cooperating.相同的初始化和请求结构适用于我的一些基本单元测试,但是当涉及到 API 到 API 通信时,Guzzle 只是不合作。

Problem:问题:

What I mean by that is, it's not including the headers I'm setting in the $headers array, and the request body is empty.我的意思是,它不包括我在$headers数组中设置的$headers ,并且请求正文为空。

Desired result:想要的结果:

To confirm this is an issue with Guzzle, I've written out the request with typical cURL syntax, and the request goes through fine.为了确认这是 Guzzle 的问题,我已经用典型的 cURL 语法写出了请求,并且请求顺利通过。 I just need some guidance on how to make this work with Guzzle, as I like the abstraction Guzzle offers over verbose cURL requests.我只需要一些关于如何使用 Guzzle 进行这项工作的指导,因为我喜欢 Guzzle 提供的抽象而不是冗长的 cURL 请求。

Working cURL request:工作 cURL 请求:

    $headers = array(
        'Authorization: Bearer '.$sharedSecret,
        'Content-Type: application/x-www-form-urlencoded',
        'Accept: application/json',
        'Content-Length: '.strlen($loginDetails),
    );

    $curlOptions = array(
        CURLOPT_URL             => API_URL.'member/SessionManager',
        CURLOPT_HTTPHEADER      => $headers,
        CURLOPT_RETURNTRANSFER  => FALSE,
        CURLOPT_HEADER          => FALSE,
        CURLOPT_FOLLOWLOCATION  => FALSE,
        CURLOPT_ENCODING        => "",
        CURLOPT_USERAGENT       => "PORTAL",
        CURLOPT_AUTOREFERER     => TRUE,
        CURLOPT_CONNECTTIMEOUT  => 120,
        CURLOPT_TIMEOUT         => 120,
        CURLOPT_MAXREDIRS       => 10,
        CURLOPT_POST            => TRUE,
        CURLOPT_POSTFIELDS      => $loginDetails,
        CURLOPT_SSL_VERIFYHOST  => FALSE,
        CURLOPT_SSL_VERIFYPEER  => FALSE,
        CURLOPT_VERBOSE         => FALSE
    );

    try {
        $ch = curl_init();
        curl_setopt_array($ch,$curlOptions);
        $content    = curl_exec($ch);
        $err        = curl_errno($ch);
        $errmsg     = curl_error($ch);
        $response   = curl_getinfo($ch);
        curl_close($ch);

        if ($content === FALSE) {
            throw new Exception(curl_error($ch), curl_errno($ch));
        } else {
            return true;
        }
    } catch(Exception $e) {
        trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
    }

The Guzzle client is initialized in a global file that creates a container which stores various objects we use throughout the application. Guzzle 客户端在一个全局文件中初始化,该文件创建了一个容器,用于存储我们在整个应用程序中使用的各种对象。 I'm including it in case I missed something vital that isn't in Guzzle's documentation.我将它包括在内,以防我错过了 Guzzle 文档中没有的重要内容。

Guzzle initialization: Guzzle 初始化:

$container['client'] = function ($c) {
    return new \GuzzleHttp\Client([
        'base_uri'          => API_URL,
        'timeout'           => 30.0,
        'allow_redirects'   => true,
        'verify'            => false,
        'verbose'           => true,
        [
            'headers'   => [
                'Authorization' => 'Bearer '.$sharedSecret,
            ]
        ],
    ]);
};

Non-working Guzzle Request:非工作 Guzzle 请求:

    $headers = array(
        'Authorization' => 'Bearer '.$sharedSecret,
        'Content-Type'  => 'application/x-www-form-urlencoded',
        'Accept'        => 'application/json',
        'Content-Length'=> strlen($loginDetails),
    );

    try {
        $response = $this->client->post('/api/member/SessionManager',
            ['debug'            => true],
            ['headers'          => $headers],
            ['body'             => $loginDetails]
        );

        if($response) {
            $this->handleResponse($response);
        }

    } catch (GuzzleHttp\Exception\ClientException $e) {
        $response->getResponse();
        $responseBodyAsString = $response->getBody()->getContents();
    }

Whether I remove the headers array in the Guzzle initialization or not, it doesn't matter.是否删除 Guzzle 初始化中的headers数组,都没有关系。 The Authorization header is nowhere to be found in the request (confirmed with tcpdump, Wireshark, and receiving API error logging), and Guzzle's debug output shows no indication of my headers, nor my request body being anywhere in the request.在请求中找不到授权标头(通过 tcpdump、Wireshark 和接收 API 错误日志确认),并且 Guzzle 的调试输出没有显示我的标头,也没有我的请求正文在请求中的任何位置。

I'm stumped as to why this isn't working, and would very much like to understand.我很难理解为什么这不起作用,并且非常想了解。 I can go the route of not using Guzzle, but would really prefer to due to brevity.我可以走不使用 Guzzle 的路线,但由于简洁,我真的更愿意。 Any input would be greatly appreciated.任何投入将不胜感激。

In cURL request, the API URL being called iscURL请求中,被调用的 API URL 是

API_URL.'member/SessionManager'

While in Guzzle request, the API URL being called has extra text "/api/" (assuming API_URL is defined same in both cases)而在Guzzle请求中,被调用的 API URL 有额外的文本“/api/”(假设 API_URL 在两种情况下定义相同)

new \\GuzzleHttp\\Client([ 'base_uri' => API_URL,

... ...

$this->client->post('/api/member/SessionManager',

Appreciate that the question is old, but I thought I'd share my experience as I also struggled with this.感谢这个问题很老,但我想我会分享我的经验,因为我也为此苦苦挣扎。 The equivalent of:相当于:

CURLOPT_POSTFIELDS      => $loginDetails,

in Guzzle is:在 Guzzle 是:

"query" => $loginDetails

In addition, I have found that if the base_uri does not end with a / , Guzzle will misunderstand it.另外,我发现如果base_uri不以/结尾,Guzzle 会误解它。

With all that in mind, your POST request should be as follows:考虑到所有这些,您的 POST 请求应如下所示:

        $response = $this->client->post('api/member/SessionManager', // Removed the first / as it's part of the base_uri now
            ['debug'            => true],
            ['headers'          => $headers],
            ['query'            => $loginDetails] // Replaced "body" with "query"
        );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM