Blob file download in Angular.js using $resource
2016-07-12 22:24
375 查看
<div ng-controller="appController" ng-app="app">
<a ng-href="{{ fileUrl }}" download="file.txt">download</a>
</div>
var app = angular.module('app', []);
app.config(['$compileProvider', function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
}]);
app.controller('appController', function ($scope, $window) {
var data = 'some data here...',
blob = new Blob([data], { type: 'text/plain' }),
url = $window.URL || $window.webkitURL;
$scope.fileUrl = url.createObjectURL(blob);
});
========================================================================================================
In this tutorial we will create a simple Angular application which can create a link of a downloadable file through $resource!
So first of all we will use XHR2 in order to use ArrayBuffer a new response type. Then we’ll use the HTML5 download attribute to name our blob file.
Let’s create our example resource called Email. Then add our custom action called getFile, in order to download the attached xlsx files.
view
rawgistfile1.js hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
Now extend it to be able to store the file in the memory. Here we have to set the sever’s responseType to ArrayBuffer. Here’s a catch: Angular can’t handle it so we have to transform the response.
All what we will do is turn the data into blob with the correct mime type.
view
rawgistfile2.js hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
Let’s create our controller method. Here we create an url for the blob we got from our API.
view
rawgistfile3.js hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
Model: done, ViewModel: done, view is the next. Here we’ll use another new feature in HTML5: the download attribute, which is used to force downloading instead of opening the file and be able to customise the name of the file. In our case it’s extremely important,
due to the blob file name is made up by a few random character. Also note target self, which is a little fix for some “browser’s”…
view
rawgistfile4.tpl.html hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
At this point we could think: Yay! We made it! But it’s just not true. Angular adds an unsafe prefix to our URL due to security reasons against blob. So at the final step we have to disable this in a config method, by adding blob to the RegEx whitelist.
view
rawgistfile5.js hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
Thanks for reading! You can check out the final code below in a gist example with inlined angular code.
view
rawgistfilefull.html hosted with
![](https://s0.wp.com/wp-content/mu-plugins/emoji/twemoji/svg/2764.svg)
by GitHub
<a ng-href="{{ fileUrl }}" download="file.txt">download</a>
</div>
var app = angular.module('app', []);
app.config(['$compileProvider', function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(|blob|):/);
}]);
app.controller('appController', function ($scope, $window) {
var data = 'some data here...',
blob = new Blob([data], { type: 'text/plain' }),
url = $window.URL || $window.webkitURL;
$scope.fileUrl = url.createObjectURL(blob);
});
========================================================================================================
In this tutorial we will create a simple Angular application which can create a link of a downloadable file through $resource!
So first of all we will use XHR2 in order to use ArrayBuffer a new response type. Then we’ll use the HTML5 download attribute to name our blob file.
Let’s create our example resource called Email. Then add our custom action called getFile, in order to download the attached xlsx files.
(function () { | |
'use strict'; | |
angular | |
.module('app') | |
.factory('Email', Email); | |
function Email($resource) { | |
var url = 'emails/' | |
, EmailBase; | |
EmailBase = $resource(url + ':emailId', {emailId: '@id'}, { | |
getFile: { | |
method: 'GET', | |
url: url + ':emailId/files/:fileName', | |
params: { | |
emailId: '@id', | |
fileName: '@fileName' | |
}, | |
cache: false | |
} | |
}); | |
return EmailBase; | |
} | |
}()); |
rawgistfile1.js hosted with
by GitHub
Now extend it to be able to store the file in the memory. Here we have to set the sever’s responseType to ArrayBuffer. Here’s a catch: Angular can’t handle it so we have to transform the response.
All what we will do is turn the data into blob with the correct mime type.
/* global Blob */ | |
(function () { | |
'use strict'; | |
angular | |
.module('app') | |
.factory('Email', Email); | |
function Email($resource) { | |
var url = 'emails/' | |
, EmailBase | |
, xlsxContentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; | |
EmailBase = $resource(url + ':emailId', {emailId: '@id'}, { | |
getFile: { | |
method: 'GET', | |
url: url + ':emailId/files/:fileName', | |
params: { | |
emailId: '@id', | |
fileName: '@fileName' | |
}, | |
headers: { | |
accept: xlsxContentType | |
}, | |
responseType: 'arraybuffer', | |
cache: false, | |
transformResponse: function (data) { | |
return { | |
response: new Blob([data], {type: xlsxContentType}) | |
}; | |
} | |
} | |
}); | |
return EmailBase; | |
} | |
}()); |
rawgistfile2.js hosted with
by GitHub
Let’s create our controller method. Here we create an url for the blob we got from our API.
/* global URL */ | |
(function () { | |
'use strict'; | |
angular | |
.module('app') | |
.controller('EmailCtrl', EmailCtrl); | |
function EmailCtrl($scope, Email) { | |
var vm = this | |
, downloadableBlob = ''; | |
vm.getUploadedFileUrl = function getUploadedFileUrl() { | |
return downloadableBlob; | |
}; | |
$scope.$on('$stateChangeSuccess', updateDownloadableBlob); | |
function updateDownloadableBlob() { | |
.getFile({ | |
emailId: 1, | |
fileName: 'some.xlsx' | |
}) | |
.$promise | |
.then(function (data) { | |
downloadableBlob = URL.createObjectURL(data.response); | |
}); | |
} | |
} | |
}()); |
rawgistfile3.js hosted with
by GitHub
Model: done, ViewModel: done, view is the next. Here we’ll use another new feature in HTML5: the download attribute, which is used to force downloading instead of opening the file and be able to customise the name of the file. In our case it’s extremely important,
due to the blob file name is made up by a few random character. Also note target self, which is a little fix for some “browser’s”…
<a target="_self" download="some.xlsx" ng-href="{{email.getUploadedFileUrl()}}"> | |
Download | |
</a> |
rawgistfile4.tpl.html hosted with
by GitHub
At this point we could think: Yay! We made it! But it’s just not true. Angular adds an unsafe prefix to our URL due to security reasons against blob. So at the final step we have to disable this in a config method, by adding blob to the RegEx whitelist.
(function () { | |
'use strict'; | |
angular | |
.module('app') | |
.config(allowBlobLinkHrefs); | |
function allowBlobLinkHrefs($compileProvider) { | |
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/); | |
} | |
}()); |
rawgistfile5.js hosted with
by GitHub
Thanks for reading! You can check out the final code below in a gist example with inlined angular code.
<!doctype html> | |
<html lang="en" data-ng-app='app' data-ng-controller="EmailCtrl as email"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Example</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script> | |
<script> | |
(function () { | |
'use strict'; | |
angular | |
.module('app') | |
.config(allowBlobLinkHrefs) | |
.controller('EmailCtrl', EmailCtrl) | |
.factory('Email', Email); | |
function Email($resource) { | |
var url = 'emails/', | |
EmailBase, xlsxContentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; | |
EmailBase = $resource(url + ':emailId', { | |
emailId: '@id' | |
}, { | |
getFile: { | |
method: 'GET', | |
url: url + ':emailId/files/:fileName', | |
params: { | |
emailId: '@id', | |
fileName: '@fileName' | |
}, | |
headers: { | |
accept: xlsxContentType | |
}, | |
responseType: 'arraybuffer', | |
cache: false, | |
transformResponse: function (data) { | |
return { | |
response: new Blob([data], { | |
type: xlsxContentType | |
}) | |
}; | |
} | |
} | |
}); | |
return EmailBase; | |
} | |
function EmailCtrl($scope, Email) { | |
var vm = this, | |
downloadableBlob = ''; | |
vm.getUploadedFileUrl = function getUploadedFileUrl() { | |
return downloadableBlob; | |
}; | |
$scope.$on('$stateChangeSuccess', updateDownloadableBlob); | |
function updateDownloadableBlob() { | |
.getFile({ | |
emailId: 1, | |
fileName: 'some.xlsx' | |
}) | |
.$promise | |
.then(function (data) { | |
downloadableBlob = URL.createObjectURL(data.response); | |
}); | |
} | |
} | |
function allowBlobLinkHrefs($compileProvider) { | |
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|blob):/); | |
} | |
}()); | |
</script> | |
</head> | |
<body> | |
<a target="_self" download="some.xlsx" ng-href="{{email.getUploadedFileUrl()}}"> | |
Download | |
</a> | |
</body> | |
</html> |
rawgistfilefull.html hosted with
by GitHub
相关文章推荐
- JS中的对象联姻:call方法
- backbonejs
- 谈谈Js内存泄漏的那点事儿
- createjs碰撞检测localToLocal的用法
- JS判断单选框是否选中
- Js判断是否有属性
- Js 替代
- Js解析json
- js解析XML
- fastJSON---List转String-String转数组
- js异步加载
- 在web服务器上运行jsp文件
- 时间js转换方法Date("149...") 转成 2016-7-12 21:23:34 009
- jsp-九大内置对象
- web.xml、JSP原理、指令
- $.getjson()【笔记】
- JavaScript实现Tab标签页切换的最简便方式
- JavaScript
- extjs4.2点击树形菜单生成tab页并访问发送请求
- 其实你根本就懂闭包