使用 angular $http.get 从服务器下载文件
Download file from server with angular $http.get
我试图在用户单击 "Download PDF" 按钮时触发文件下载。调用 API 进行一些检查,然后调用 returns 文件。我不想在浏览器中打开该文件。我已经阅读了很多关于如何执行此操作的 Whosebug-questions,但无法让它工作。我将文件内容作为文本返回,但浏览器不保存文件,也没有让我选择将其保存为文件。
这就是我的。
HTML
<button ng-click="apiDownload()">Download PDF</button>
AngularJS 控制器
$scope.apiDownload = function(){
var config = {
method: 'GET',
url: "/api/download",
headers: {
'Accept': 'application/pdf'
}
};
$http(config)
.success(function(res){
console.log(res);
})
.error(function(res){});
};
PHP API(主要来自here)
function apiDownloadFile() {
$file_name = "download/test.pdf";
$abs_file_name = realpath(dirname(__FILE__)).'/'.$file_name;
if(is_file($abs_file_name) && file_exists($abs_file_name)) {
// required for IE
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
// get the file mime type using the file extension
switch(strtolower(substr(strrchr($file_name, '.'), 1))) {
case 'pdf': $mime = 'application/pdf'; break;
case 'zip': $mime = 'application/zip'; break;
case 'jpeg':
case 'jpg': $mime = 'image/jpg'; break;
default: $mime = 'application/force-download';
}
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($abs_file_name)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename='.basename($abs_file_name));
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($abs_file_name)); // provide file size
header('Connection: close');
readfile($abs_file_name); // push it out
exit();
}
}
我在 chrome 开发者工具中看到这些 headers:
请求Headers
GET /api/download HTTP/1.1
Host: sa.dev
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: application/pdf
If-Modified-Since: 0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Referer: https://sa.dev/insights
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,da;q=0.6,sv;q=0.4,no;q=0.2,nb;q=0.2
Cookie: ...
回复Headers
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2015 14:27:08 GMT
Server: Apache/2.4.9 (Unix) PHP/5.6.5 OpenSSL/0.9.8zc
X-Powered-By: PHP/5.6.5
Pragma: public
Expires: 0
Cache-Control: must-revalidate, post-check=0, pre-check=0
Last-Modified: Mon, 16 Mar 2015 09:04:06 GMT
Cache-Control: private
Content-Disposition: attachment; filename=test.pdf
Content-Transfer-Encoding: binary
Content-Length: 5501633
Connection: close
Content-Type: application/pdf
我使用 John Culviner's jQuery.fileDownload library (see this SO-answer).
解决了这个问题
使用 jQuery.fileDownload 时,我必须向 my code 添加两件事。
设置 cookie
- 在PHP中:
setcookie('fileDownload', "true", NULL, '/');
- Set-Cookie header 将如下所示:
Set-Cookie: fileDownload=true; path=/
从js调用$.fileDownload('/api/download');
。并删除 angular $http.
的使用
有关如何使用 jQuery.fileDownload 的更多信息,请参阅 this blog。
如果有人有不使用 jQuery 库的解决方案,请随时 post 作为答案。
$scope.apiDownload = function(){
window.open('api/download');
};
效果很好
我试图在用户单击 "Download PDF" 按钮时触发文件下载。调用 API 进行一些检查,然后调用 returns 文件。我不想在浏览器中打开该文件。我已经阅读了很多关于如何执行此操作的 Whosebug-questions,但无法让它工作。我将文件内容作为文本返回,但浏览器不保存文件,也没有让我选择将其保存为文件。
这就是我的。
HTML
<button ng-click="apiDownload()">Download PDF</button>
AngularJS 控制器
$scope.apiDownload = function(){
var config = {
method: 'GET',
url: "/api/download",
headers: {
'Accept': 'application/pdf'
}
};
$http(config)
.success(function(res){
console.log(res);
})
.error(function(res){});
};
PHP API(主要来自here)
function apiDownloadFile() {
$file_name = "download/test.pdf";
$abs_file_name = realpath(dirname(__FILE__)).'/'.$file_name;
if(is_file($abs_file_name) && file_exists($abs_file_name)) {
// required for IE
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
// get the file mime type using the file extension
switch(strtolower(substr(strrchr($file_name, '.'), 1))) {
case 'pdf': $mime = 'application/pdf'; break;
case 'zip': $mime = 'application/zip'; break;
case 'jpeg':
case 'jpg': $mime = 'image/jpg'; break;
default: $mime = 'application/force-download';
}
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($abs_file_name)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename='.basename($abs_file_name));
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($abs_file_name)); // provide file size
header('Connection: close');
readfile($abs_file_name); // push it out
exit();
}
}
我在 chrome 开发者工具中看到这些 headers:
请求Headers
GET /api/download HTTP/1.1
Host: sa.dev
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: application/pdf
If-Modified-Since: 0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Referer: https://sa.dev/insights
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,da;q=0.6,sv;q=0.4,no;q=0.2,nb;q=0.2
Cookie: ...
回复Headers
HTTP/1.1 200 OK
Date: Mon, 16 Mar 2015 14:27:08 GMT
Server: Apache/2.4.9 (Unix) PHP/5.6.5 OpenSSL/0.9.8zc
X-Powered-By: PHP/5.6.5
Pragma: public
Expires: 0
Cache-Control: must-revalidate, post-check=0, pre-check=0
Last-Modified: Mon, 16 Mar 2015 09:04:06 GMT
Cache-Control: private
Content-Disposition: attachment; filename=test.pdf
Content-Transfer-Encoding: binary
Content-Length: 5501633
Connection: close
Content-Type: application/pdf
我使用 John Culviner's jQuery.fileDownload library (see this SO-answer).
解决了这个问题使用 jQuery.fileDownload 时,我必须向 my code 添加两件事。
设置 cookie
- 在PHP中:
setcookie('fileDownload', "true", NULL, '/');
- Set-Cookie header 将如下所示:
Set-Cookie: fileDownload=true; path=/
- 在PHP中:
从js调用
$.fileDownload('/api/download');
。并删除 angular $http. 的使用
有关如何使用 jQuery.fileDownload 的更多信息,请参阅 this blog。
如果有人有不使用 jQuery 库的解决方案,请随时 post 作为答案。
$scope.apiDownload = function(){
window.open('api/download');
};
效果很好