Скачать текстовый контент/CSV как файлы с сервера в угловой
Я пытаюсь передать a csv
файл с узла.сервер JS. Серверная часть очень проста:
server.get('/orders' function(req, res) {
res.setHeader('content-type', 'text/csv');
res.setHeader('content-disposition', 'attachment; filename='orders.csv');
return orders.pipe(res); // assuming orders is a csv file readable stream (doesn't have to be a stream, can be a normal response)
}
в моем угловом контроллере я пытаюсь сделать что-то вроде этого
$scope.csv = function() {
$http({method: 'GET', url: '/orders'});
};
эта функция вызывается при нажатии на кнопку с ng-click
на мой взгляд :
<button ng-click="csv()">.csv</button>
Я посмотрел на другие ответы о загрузке файлов с сервера в Angular, но не нашел ничего, что работало для меня. Есть ли общий способ сделать это ? Кажется, что-то, что должно быть простым.
5 ответов:
$http
сервис возвращает apromise
, который имеет два метода обратного вызова, как показано ниже.$http({method: 'GET', url: '/someUrl'}). success(function(data, status, headers, config) { var anchor = angular.element('<a/>'); anchor.attr({ href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data), target: '_blank', download: 'filename.csv' })[0].click(); }). error(function(data, status, headers, config) { // handle error });
большинство ссылки в интернете об этой проблеме указывают на то, что вы не можете загружать файлы с помощью ajax вызова "из коробки". Я видел (хакерские) решения, которые включают
iframes
а также такие решения, как @dcodesmith, которые работают и совершенно жизнеспособны.вот еще одно решение, которое я нашел, которое работает в угловом и очень прямолинейно.
на view, оберните скачать с
<a>
тег следующим образом :<a target="_self" ng-href="{{csv_link}}"> <button>download csv</button> </a>
(уведомление
target="_self
там, важно отключить маршрутизацию Angular внутри ng-приложения подробнее об этом здесь)внутри вы контроллер вы можете определить
csv_link
следующим образом :$scope.csv_link = '/orders' + $window.location.search;
(the
$window.location.search
является необязательным и onlt, если вы хотите передать дополнительный поисковый запрос на ваш сервер)теперь каждый раз, когда вы нажимаете кнопку, он должен начать загрузку.
var anchor = angular.element('<a/>'); anchor.css({display: 'none'}); // Make sure it's not visible angular.element(document.body).append(anchor); // Attach to document anchor.attr({ href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data), target: '_blank', download: 'filename.csv' })[0].click(); anchor.remove(); // Clean it up afterwards
этот код работает как Mozilla, так и chrome
Это то, что работало для меня для IE 11+, Firefox и Chrome. В safari он загружает файл, но как неизвестный и имя файла не установлено.
if (window.navigator.msSaveOrOpenBlob) { var blob = new Blob([csvDataString]); //csv data string as an array. // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx window.navigator.msSaveBlob(blob, fileName); } else { var anchor = angular.element('<a/>'); anchor.css({display: 'none'}); // Make sure it's not visible angular.element(document.body).append(anchor); // Attach to document for FireFox anchor.attr({ href: 'data:attachment/csv;charset=utf-8,' + encodeURI(csvDataString), target: '_blank', download: fileName })[0].click(); anchor.remove(); }
С помощью угловой 1.5.9
Я сделал это работает так, установив окно.расположение к url-адресу загрузки файла csv. Протестировано и его работа с последней версией Chrome и IE11.
Угловое
$scope.downloadStats = function downloadStats{ var csvFileRoute = '/stats/download'; $window.location = url; }
html
<a target="_self" ng-click="downloadStats()"><i class="fa fa-download"></i> CSV</a>
на php установите следующие заголовки для ответа:
$headers = [ 'content-type' => 'text/csv', 'Content-Disposition' => 'attachment; filename="export.csv"', 'Cache-control' => 'private, must-revalidate, post-check=0, pre-check=0', 'Content-transfer-encoding' => 'binary', 'Expires' => '0', 'Pragma' => 'public', ];