返回文件流官方說明是這個
<?php
namespace app\controller;
use support\Request;
class FooController
{
public function hello(Request $request)
{
return response()->file(public_path() . '/favicon.ico');
}
}
webman支持發(fā)送超大文件
對于大文件(超過2M),webman不會將整個文件一次性讀入內(nèi)存,而是在合適的時機分段讀取文件并發(fā)送
webman會根據(jù)客戶端接收速度來優(yōu)化文件讀取發(fā)送速度,保證最快速發(fā)送文件的同時將內(nèi)存占用減少到最低
數(shù)據(jù)發(fā)送是非阻塞的,不會影響其它請求處理
file方法會自動添加if-modified-since頭并在下一個請求時檢測if-modified-since頭,如果文件未修改則直接返回304以便節(jié)省帶寬
發(fā)送的文件會自動使用合適的Content-Type頭發(fā)送給瀏覽器
如果文件不存在,會自動轉(zhuǎn)為404響應(yīng)
如果我是要請求一個遠程url,他會驗證我的秘鑰,然后返回一個文件流給我,我怎么返回到前端去呢,對方既不給文件名,也不返文件長度給我,就一個文件流,還不能Range斷點續(xù)傳。
我之前是先下載到webman服務(wù)器本地,存起來,再返給前端,但是這樣大文件超過2.1GB請求會直接報錯,也不知道是哪里設(shè)置的緩存太小還是怎么,報錯如下:
cURL error 18: transfer closed with outstanding read data remaining (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) ;
我能否直接轉(zhuǎn)發(fā)這個文件流到前端去,而不再轉(zhuǎn)存到本地,這種4個GB的文件能正常轉(zhuǎn)發(fā)嗎?轉(zhuǎn)發(fā)怎么寫呢,curl獲取文件流,然后 $result = curl_exec($ch),再return $result嗎?
之前用guzzle下載是這樣寫的:
$pdfFileResource = fopen($file_path_and_name, 'w+');
$httpClient = new Client();
$response = $httpClient->get($url,[RequestOptions::SINK => $pdfFileResource,'headers'=>$headers,'timeout'=>0]);
<?php
namespace app\controller;
use support\Request;
use Workerman\Http\Client;
use Workerman\Protocols\Http\Chunk;
class DownloadController
{
public function index(Request $request)
{
$connection = $request->connection;
$http = new Client();
$http->request('https://example.com/xxx.pdf', [
'method' => 'GET',
'progress' => function($buffer) use ($connection) {
$connection->send(new Chunk($buffer));
},
'success' => function($response) use ($connection) {
$connection->send(new Chunk('')); // 發(fā)送空的的chunk代表response結(jié)束
},
]);
return response()->withHeaders([
"Content-Type" => "application/pdf",
"Transfer-Encoding" => "chunked",
]);
}
}
代碼類似這樣。
文檔參考 http://wtbis.cn/doc/workerman/components/workerman-http-client.html
public function downloadFile(Request $request)
{
$url = "https://api.aliyun.com/api/downfile;
$headers = [
"APPID"=>config('static.APPID'),
"APPKEY"=>config('static.APPKEY'),
];
$connection = $request->connection;
$http = new \Workerman\Http\Client();
$http->request($url, [
'method' => 'GET',
'progress' => function($buffer) use ($connection) {
$connection->send(new Chunk($buffer));
},
'success' => function($response) use ($connection) {
$connection->send(new Chunk('')); // 發(fā)送空的的chunk代表response結(jié)束
},
'headers' => $headers,
]);
return response()->withHeaders([
"Transfer-Encoding" => "chunked",
]);
}
這樣寫沒用,前端點這個按鈕沒反應(yīng)
對的,需求就是下載這個文件,我獲取一個文件id,然后http請求一個遠程地址,通過API,他會返一個文件流給我,但是有4個G,我之前都是直接下載到服務(wù)器,這個4GB的文件,我下不了,每次一到2.1G左右都報錯 “cURL error 18: transfer closed with outstanding read data remaining” ,所以我才想能不能直接轉(zhuǎn)發(fā)這個流給前端,但是有點不好處理,網(wǎng)上的案例都是遠程地址是個 xxx.com/xxx/xxx.pdf ,這種資源文件地址,但我這個其實是個API接口,他通過驗證才會返文件流