У мене є текст у прихованій текстовій області. Коли натискається кнопка, я хотів би, щоб текст пропонувався для завантаження як .txtфайл. Чи можливо це за допомогою AngularJS або Javascript?
У мене є текст у прихованій текстовій області. Коли натискається кнопка, я хотів би, щоб текст пропонувався для завантаження як .txtфайл. Чи можливо це за допомогою AngularJS або Javascript?
Відповіді:
Ви можете зробити щось подібне за допомогою Blob.
<a download="content.txt" ng-href="{{ url }}">download</a>
у вашому контролері:
var content = 'file content for example';
var blob = new Blob([ content ], { type : 'text/plain' });
$scope.url = (window.URL || window.webkitURL).createObjectURL( blob );
щоб увімкнути URL-адресу:
app = angular.module(...);
app.config(['$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/);
}]);
Будь ласка, зверніть увагу, що
Кожного разу, коли ви викликаєте createObjectURL (), створюється нова URL-адреса об’єкта, навіть якщо ви вже створили одну для того самого об’єкта. Кожен із них потрібно звільнити, викликавши URL.revokeObjectURL (), коли вони вам більше не потрібні. Браузери випускають їх автоматично, коли документ вивантажується; однак для оптимальної роботи та використання пам'яті, якщо є безпечні часи, коли ви можете явно їх вивантажити, вам слід це зробити.
Джерело: MDN
$scope.urlмені не вдалося. Мені довелося використовувати window.locationзамість цього.
downloadАтрибут не підтримуються в IE будь-якої версії або Safari , хоча caniuse.com/#feat=download
Просто натисніть кнопку для завантаження за допомогою наступного коду.
в HTML
<a class="btn" ng-click="saveJSON()" ng-href="{{ url }}">Export to JSON</a>
У контролері
$scope.saveJSON = function () {
$scope.toJSON = '';
$scope.toJSON = angular.toJson($scope.data);
var blob = new Blob([$scope.toJSON], { type:"application/json;charset=utf-8;" });
var downloadLink = angular.element('<a></a>');
downloadLink.attr('href',window.URL.createObjectURL(blob));
downloadLink.attr('download', 'fileName.json');
downloadLink[0].click();
};
$http.get(...)переконайтеся , що встановили , responseType:'arraybuffer'як описано тут: stackoverflow.com/questions/21628378 / ...
Спробуйте це
<a target="_self" href="mysite.com/uploads/ahlem.pdf" download="foo.pdf">
та відвідайте цей сайт, це може бути для вас корисним :)
downloadатрибута, який досі не підтримується жодною версією IE та Safari. Ознайомтесь тут: caniuse.com/#feat=download
Це можна зробити у javascript без необхідності відкривати інше вікно браузера.
window.location.assign('url');
Замініть "url" посиланням на ваш файл. Ви можете помістити це у функцію і викликати це, ng-clickякщо вам потрібно ініціювати завантаження за допомогою кнопки.
У нашому поточному проекті на роботі у нас був невидимий iFrame, і мені довелося подати URL-адресу для файлу в iFrame, щоб отримати діалогове вікно завантаження. Після натискання кнопки контролер генерує динамічну URL-адресу та запускає подія $ range, де directiveперерахований я написаний користувачем список. Директива додасть iFrame до тіла, якщо він вже не існує, і встановить на нього атрибут url.
EDIT: Додавання директиви
appModule.directive('fileDownload', function ($compile) {
var fd = {
restrict: 'A',
link: function (scope, iElement, iAttrs) {
scope.$on("downloadFile", function (e, url) {
var iFrame = iElement.find("iframe");
if (!(iFrame && iFrame.length > 0)) {
iFrame = $("<iframe style='position:fixed;display:none;top:-1px;left:-1px;'/>");
iElement.append(iFrame);
}
iFrame.attr("src", url);
});
}
};
return fd;
});
Ця директива відповідає на виклик події контролера downloadFile
так у вашому контролері ви робите
$scope.$broadcast("downloadFile", url);
Ви можете встановити location.hrefв даних URI , що містить дані , які ви хочете , щоб дозволити завантаження користувача. Окрім цього, я не думаю, що існує спосіб зробити це лише за допомогою JavaScript.
$location.hrefзмінено на$window.location.href
Я хотів би лише додати, що на випадок, якщо файл не завантажиться через небезпечний: blob: null ... коли ви наводите курсор на кнопку завантаження, ви повинні його продезінфікувати. Наприклад,
var app = angular.module ('app', []);
app.config (функція ($ compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
Якщо у вас є доступ до сервера, розгляньте налаштування заголовків, як відповіли в цьому більш загальному питанні .
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=\"filename.xxx\"
Читаючи коментарі до цієї відповіді, доцільно використовувати більш конкретний тип вмісту, ніж октет-потік.
У мене була та сама проблема, і я витрачав багато годин на пошук різних рішень, і тепер я приєднуюсь до всіх коментарів у цьому дописі. Сподіваюся, це буде корисним, моя відповідь була правильно перевірена в Internet Explorer 11, Chrome та FireFox.
HTML:
<a href="#" class="btn btn-default" file-name="'fileName.extension'" ng-click="getFile()" file-download="myBlobObject"><i class="fa fa-file-excel-o"></i></a>
ДИРЕКТИВА:
directive('fileDownload',function(){
return{
restrict:'A',
scope:{
fileDownload:'=',
fileName:'=',
},
link:function(scope,elem,atrs){
scope.$watch('fileDownload',function(newValue, oldValue){
if(newValue!=undefined && newValue!=null){
console.debug('Downloading a new file');
var isFirefox = typeof InstallTrigger !== 'undefined';
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
var isIE = /*@cc_on!@*/false || !!document.documentMode;
var isEdge = !isIE && !!window.StyleMedia;
var isChrome = !!window.chrome && !!window.chrome.webstore;
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
var isBlink = (isChrome || isOpera) && !!window.CSS;
if(isFirefox || isIE || isChrome){
if(isChrome){
console.log('Manage Google Chrome download');
var url = window.URL || window.webkitURL;
var fileURL = url.createObjectURL(scope.fileDownload);
var downloadLink = angular.element('<a></a>');//create a new <a> tag element
downloadLink.attr('href',fileURL);
downloadLink.attr('download',scope.fileName);
downloadLink.attr('target','_self');
downloadLink[0].click();//call click function
url.revokeObjectURL(fileURL);//revoke the object from URL
}
if(isIE){
console.log('Manage IE download>10');
window.navigator.msSaveOrOpenBlob(scope.fileDownload,scope.fileName);
}
if(isFirefox){
console.log('Manage Mozilla Firefox download');
var url = window.URL || window.webkitURL;
var fileURL = url.createObjectURL(scope.fileDownload);
var a=elem[0];//recover the <a> tag from directive
a.href=fileURL;
a.download=scope.fileName;
a.target='_self';
a.click();//we call click function
}
}else{
alert('SORRY YOUR BROWSER IS NOT COMPATIBLE');
}
}
});
}
}
})
У КОНТРОЛЕРІ:
$scope.myBlobObject=undefined;
$scope.getFile=function(){
console.log('download started, you can show a wating animation');
serviceAsPromise.getStream({param1:'data1',param1:'data2', ...})
.then(function(data){//is important that the data was returned as Aray Buffer
console.log('Stream download complete, stop animation!');
$scope.myBlobObject=new Blob([data],{ type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
},function(fail){
console.log('Download Error, stop animation and show error message');
$scope.myBlobObject=[];
});
};
В СЛУЖБІ:
function getStream(params){
console.log("RUNNING");
var deferred = $q.defer();
$http({
url:'../downloadURL/',
method:"PUT",//you can use also GET or POST
data:params,
headers:{'Content-type': 'application/json'},
responseType : 'arraybuffer',//THIS IS IMPORTANT
})
.success(function (data) {
console.debug("SUCCESS");
deferred.resolve(data);
}).error(function (data) {
console.error("ERROR");
deferred.reject(data);
});
return deferred.promise;
};
БЕКЕНД (на ВЕСНУ):
@RequestMapping(value = "/downloadURL/", method = RequestMethod.PUT)
public void downloadExcel(HttpServletResponse response,
@RequestBody Map<String,String> spParams
) throws IOException {
OutputStream outStream=null;
outStream = response.getOutputStream();//is important manage the exceptions here
ObjectThatWritesOnOutputStream myWriter= new ObjectThatWritesOnOutputStream();// note that this object doesn exist on JAVA,
ObjectThatWritesOnOutputStream.write(outStream);//you can configure more things here
outStream.flush();
return;
}
Це працювало для мене в кутовому:
var a = document.createElement("a");
a.href = 'fileURL';
a.download = 'fileName';
a.click();
data:text/plain;base64,${btoa(theStringGoesHere)}
Я не хотів статичну URL-адресу. У мене є AjaxFactory для виконання всіх операцій ajax. Я отримую URL-адресу із заводу та прив’язую її наступним чином.
<a target="_self" href="{{ file.downloadUrl + '/' + order.OrderId + '/' + fileName }}" download="{{fileName}}">{{fileName}}</a>
Дякую @AhlemMustapha