php - Laravel API 返回文件并且客户端必须显示下载对话框
问题描述
我正在开发一个 Laravel 5.3 API Bridge 来将一些文件下载到各种系统。我想要达到的目标:
- 用户点击下载按钮
- PHP Web 向 API 发出 cURL 发布请求
- API 响应可能是文件或 404 HTTP 代码
- 客户端浏览器显示文件下载对话框
接口方法:
$reportService = new ReportService($request->get('vRefGMS'));
$reportData = $reportService->handle();
if ($reportData) {
$serverService = new NetServerService($reportData);
$csvFile = $serverService->handle();
if ($csvFile != null) {
return response()->file($csvFile);
} else {
return abort(404);
}
} else {
return abort(404);
}
现在我将向您展示我尝试过的代码。
网页中的 PHP 代码供下载:
$uri = $this->getEndpointShow($this->reportCode, SELF::ENDPOINT_REPORT_DOWNLOAD);
$file = $this->apiConnection->downloadReport($uri, $this->reportCode);
if ($file) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
flush();
readfile($file);
} else {
echo "alert('Can´t find a report file')";
}
和 downloadReport 方法:
public function downloadReport($uri, $reportCode)
{
if (!$reportCode) {
throw new InvalidArgumentException("No report Code");
}
$cURLConnection = curl_init();
curl_setopt($cURLConnection, CURLOPT_URL, self::BASE_API_URL . $uri);
curl_setopt($cURLConnection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cURLConnection, CURLOPT_POST, TRUE);
curl_setopt($cURLConnection, CURLOPT_POSTFIELDS, "vRefGMS=$reportCode");
curl_setopt($cURLConnection, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . self::API_ACCESS_TOKEN
]);
$response = curl_exec($cURLConnection);
if ($response === false) {
throw new Exception(curl_error($cURLConnection), curl_errno($cURLConnection));
}
curl_close($cURLConnection);
return $response;
}
正如您在下载的 PHP 代码中看到的那样,我有一个$file
始终为空白的 var $file = ''
。我也尝试过return response()->download($csvFile)
使用相同结果的 api。
可能是我误解了概念,但我无法实现文件下载。怎样才能得到这个文件?
编辑:
该api正在返回一个文件,因为如果我继续使用cli向API发出cURL请求,那就是响应:
curl http://localhost:8080/test
StatusCode : 200
StatusDescription : OK
Content : 1;!;1;1;
RawContent : HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 8
Cache-Control: public
Date: Mon, 24 Feb 2020 01:59:37 GMT
Last-Modified: Mon, 24 Feb 2020 12:11:04 GMT
Set-Cookie: XSRF-TOKEN=eyJpdiI6ImdFb...
Forms : {}
Headers : {[Accept-Ranges, bytes], [Content-Length, 8], [Cache-Control, public], [Date, Mon, 24 Feb 2020
01:59:37 GMT]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 8
那么我在显示空白文件的网络代码中做错了什么?
解决方案
推荐阅读
- c# - 从 DbSet 中删除记录会在 EF Core 中引发“值不能为空”错误
- c# - 如何根据特定值从对象列表中获取对象?C#
- i18next - i18next::backendConnector: TypeError: 仅支持绝对 URL
- gnupg - GPG 将秘密移至 Yubikey 时添加地铁
- mongodb - 如何在 MongoDB 中创建具有不同过滤器的多个聚合?
- python - 如何为熊猫中的每一行获取上一行和下一行的序列
- javascript - 从 chrome 扩展插入 iframe 在某些网站上不起作用
- database-design - 关于数据库设计的问题 - 表层次结构
- log4j2 - Pulsar Log4j2 Appender 错误:名称为“pulsar-log4j2-appender-applog-json”的生产者已连接到主题
- javascript - 将数组减少为具有嵌套键的对象,用于将搜索查询传递给 Mongoose 中的 Model.find