使用 Guzzle 下载文件

Download File With Guzzle

我正在尝试使用 Guzzle 检索文件附件。该文件不能直接通过端点获得,但下载是通过端点启动并下载到我的浏览器的。我可以使用 Guzzle 检索此文件吗?

我成功登录了站点,但是保存到我的文件中的是站点的 html 而不是下载。当我使用 insomnia rest 客户端发出请求时,文件内容似乎通过了,但使用 Guzzle 却没有。

$client = new GuzzleHttp\Client();
$cookieJar = new \GuzzleHttp\Cookie\CookieJar();

$response = $client->post('https://test.com/login', [
    'form_params' => [
        'username' => $username,
        'password' => $password,
        'action' => 'login'
    ],
    'cookies' => $cookieJar
]);

$resource = fopen(__DIR__.'/../../feeds/test.xls', 'w');
$stream = GuzzleHttp\Psr7\stream_for($resource);
$response = $client->request('GET', 'https://test.com/download', ['sink' => $stream]);

您应该发送 Content-Disposition header 以指定客户端应接收文件下载作为响应。根据你的 GET HTTP request 将内容捕获到 $stream 资源中,最后你可以将这些内容输出到浏览器 stream_get_contents.

<?php 

// your 3rd party end-point authentication

...

header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="test.xls"'); 

$resource = fopen(__DIR__.'/../../feeds/test.xls', 'w');
$stream = GuzzleHttp\Psr7\stream_for($resource);
$response = $client->request('GET', 'https://test.com/download', ['sink' => $stream]);

echo stream_get_contents($stream);

如果您想执行身份验证步骤,然后执行下载步骤,您需要确保 cookie 在 两个 请求中保持不变。现在您只是将 $cookieJar 变量传递给第一个变量。

这样做的明确方法是将其添加到第二个请求的选项中:

['sink' => $stream, 'cookies' => $cookieJar]

但利用客户端构造函数本身的选项可能更容易:

$client = new GuzzleHttp\Client(['cookies' => true);

这意味着(针对该客户端的)每个请求都会自动使用一个共享的 cookie jar,您无需担心将其分别传递到每个请求中。