问答 / 6 / 19 / 创建于 1年前 / 更新于 1年前
第三方远程文件如 http://www.baidu.com/测试.pdfresponse()->file 用不了远程文件
use GuzzleHttp\Client; use GuzzleHttp\RequestOptions; //远程文件路径 $remoteFileUrl="http://www.gov.cn/zhengce/pdfFile/2021_PDF.pdf"; //本地存储路径绝对地址 $saveFilePath=__DIR__ . "/test_download.pdf"; try { $pdfFileResource = fopen($saveFilePath, 'w+'); $httpClient = new Client(); $response = $httpClient->get( $remoteFileUrl, [RequestOptions::SINK => $pdfFileResource] ); if ($response->getStatusCode() === 200) { echo "下载成功:".$saveFilePath; } echo "下载失败"; }catch (\Throwable $e){ var_dump($e->getMessage()); }
感谢回复,不是下载,是我获取远程地址,然后转换成文件流写成一个api给其他用户调用,效果类似
$file = storage_path() . '/data/adware.zip';//这里需要改成第三方cdn附件地址 Header("Content-Disposition: attachment; filename=adware.zip"); return response()->file($file);
然后用户使用GuzzleHttp请求我的接口,他得到是附件文件流
那也可以先下载下来,因为相当于缓存,不然下次别人下同样的文件你还再读取远程。
@yyy123456 有什么好的方案,希望服务器做中转,使用七牛云附件下载,服务器下载人少还行,人多容易搞崩掉
走到你服务器,然后你一个 location 跳转到七牛就行了,浏览器检测到文件会自动弹出下载
可以有偿解决
如果文件的 URL 有规律的话,可以单独搞一台服务器用 Nginx 做反向代理。不过还是推荐直接在 CDN 上做回源到远端服务器,这样用户访问的是你的域名,但是下载的是第三方的文件!
例如我们的测试服 OSS 用的是 MinIO,生产环境用的是 AWS S3,为了避免有些静态资源在开发环境和生产环境需要上传两次,我们将开发环境响应为 404 的请求转发到 S3 上去。
这样只需要在生产环境上传图片,就能兼容开发和生产两个环境的请求!
nginx反向代理呗
装个七牛云的磁盘驱动,或者看一下七牛云的 S3 兼容文档用 S3 的驱动,下载文件
$filePath = "http://www.baidu.com/测试.pdf"; $filename = "ceshi.pdf"; header("Content-Encoding: UTF-8"); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=".'"'.$filename.'"'); $old = fopen($filePath,"r"); $new = fopen("php://output","w+"); stream_copy_to_stream($old,$new); fclose($old); fclose($new); exit();
symfony/src/Symfony/Component/HttpFoundation/BinaryFileResponse
你看下 这个文件,能不能解决, 不支持远程文件调用
根据 BinaryFileResponse::prepare(Request $request) 封装下
BinaryFileResponse::prepare(Request $request)
最简单的用例
// routes/web.php Route::get('/test', function (){ return BinaryFileResponse::create(__FILE__, 200, [ 'Content-Type' => 'application/octet-stream' ]); });
我是这么处理的 ResponseFactoryMacro.php
<?php namespace App\Macros; use GuzzleHttp\Client; use Symfony\Component\HttpFoundation\StreamedResponse; /** * @see https://github.com/TitasGailius/laravel-stream-remote * * @mixin \Illuminate\Routing\ResponseFactory */ class ResponseFactoryMacro { /** * ``` * return response()->streamRemoteDownload( * 'https://example.com/remote/file.zip', * 'archive.zip', * ['Content-Type' => 'application/zip'], * 'attachment', * 1024 * ); * ``` */ public function streamRemoteDownload(): \Closure { return function ( string $url, ?string $name = null, array $headers = [], ?string $disposition = 'attachment', int $chunk = 2048, ?Client $client = null ): StreamedResponse { $client ??= new Client(); return $this->streamDownload(function () use ($client, $url, $chunk) { $body = $client->get($url, ['stream' => true])->getBody(); while (! $body->eof()) { echo $body->read($chunk); } }, $name, $headers, $disposition); }; } }
简单即是美
我要举报该,理由是:
走到你服务器,然后你一个 location 跳转到七牛就行了,浏览器检测到文件会自动弹出下载
可以有偿解决
如果文件的 URL 有规律的话,可以单独搞一台服务器用 Nginx 做反向代理。不过还是推荐直接在 CDN 上做回源到远端服务器,这样用户访问的是你的域名,但是下载的是第三方的文件!
例如我们的测试服 OSS 用的是 MinIO,生产环境用的是 AWS S3,为了避免有些静态资源在开发环境和生产环境需要上传两次,我们将开发环境响应为 404 的请求转发到 S3 上去。
这样只需要在生产环境上传图片,就能兼容开发和生产两个环境的请求!
nginx反向代理呗
装个七牛云的磁盘驱动,或者看一下七牛云的 S3 兼容文档用 S3 的驱动,下载文件
symfony/src/Symfony/Component/HttpFoundation/BinaryFileResponse
你看下 这个文件,能不能解决, 不支持远程文件调用
根据
BinaryFileResponse::prepare(Request $request)
封装下最简单的用例
我是这么处理的 ResponseFactoryMacro.php
简单即是美