返回GuzzleHttp响应对象会导致浏览器中出现ERR_INVALID_CHUNKED_ENCODING

问题描述:

I'm using guzzle 6 in laravel 5 to send a post request but I'm getting ERR_INVALID_CHUNKED_ENCODING when I try to access the request() in the method that handles the post request.

Here's my code:

Routes.php

Route::get('/guzzle', [
    'as'   => 'guzzle-test',
    'uses' => 'TestController@getTest'
]);

Route::post('/guzzle', [
   'as'   => 'guzzle-post-test',
   'uses' => 'TestController@postTest'
]);

TestController.php

public function getTest()
{
    $client = new Client();

    $data = [
        'hey' => 'ho'
    ];

    $request = $client->post(route('guzzle-post-test'), [
        'content-type' => 'application/json'
    ], json_encode($data));

    return $request;
}

public function postTest()
{
    dd(getTest());
}

I getting to the post request handler since I've tried to diedump a string and it gets there, but if i call the request() I get that error. For what I've researched It may have something to with the content length, but after reading guzzle's docs and some stuff around the web I could find how to get and pass the content length appropriately in the request. Any help would be very appreciated!

First off, here's some test code which you should be able to adapt for your purposes (also see form_params in the docs for GuzzleHttp):

public function validateRecaptcha()
{
    $client = new Client;
    $response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'secret' => env('RECAPTCHA_SECRET'),
                'response' => Request::input('g-recaptcha-response'),
                'remoteip' => Request::ip()
            ]
    ]);

    return $response;
}

I just ran into the same issue and found that trying to return the response object in Laravel gave me ERR_INVALID_CHUNKED_ENCODING. Whereas, doing a dd() on the response itself showed me what I was actually wanting to see:

public function validateRecaptcha()
{
    $client = new Client;
    $response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'secret' => env('RECAPTCHA_SECRET'),
                'response' => Request::input('g-recaptcha-response'),
                'remoteip' => Request::ip()
            ]
    ]);

    dd($response);
}

Unfortunately, without doing further research, I'm unable to explain why ERR_INVALID_CHUNKED_ENCODING keeps coming up when I try to return the client library's objects to the browser, but my initial inclination is that it's a data type issue.

As far as your question goes, you're not actually trying to get back the "request" but rather the response. According to http://docs.guzzlephp.org/en/latest/quickstart.html#using-responses, if you want to get the API response contained in the response object (or at least in my case, I did), you'll want to use the getBody() method:

public function validateRecaptcha()
{
    $client = new Client;
    $response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'secret' => env('RECAPTCHA_SECRET'),
                'response' => Request::input('g-recaptcha-response'),
                'remoteip' => Request::ip()
            ]
    ]);

    return $response->getBody();
}

And then of course, if you expect it to be a JSON response (i.e. REST), then simply pass it to json_decode() to get your associative array back.

public function validateRecaptcha()
{
    $client = new Client;
    $response = $client->request('POST', 'https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'secret' => env('RECAPTCHA_SECRET'),
                'response' => Request::input('g-recaptcha-response'),
                'remoteip' => Request::ip()
            ]
    ]);

    return json_decode($response->getBody(), true); // true = assoc. array
}

Hope that helps!