【发布时间】:2016-05-02 20:33:02
【问题描述】:
我的用户有需要由经过身份验证的用户下载的私人文件。我的服务器首先使用它自己的 S3 app_id/secret_token 凭据从 S3 下载文件。然后使用 Rails 的send_data 方法构造下载的文件并发送到客户端。
Ruby(在 Rails 上):
# documents_controller.rb
def download
some_file = SomeFile.find(params[:id])
# download file from AWS S3 to server
data = open(some_file.document.url)
# construct and send downloaded file to client
send_data data.read, filename: some_file.document_identifier, disposition: 'inline', stream: 'true'
end
最初,我想直接从 HTML 模板触发下载。
HTML:
<!-- download-template.html -->
<a target="_self" ng-href="{{ document.download_url }}" download="{{document.file_name}}">Download</a>
看起来很简单,但问题是 Angular 的 $http 拦截器没有捕捉到这种类型的外部链接点击,因此没有为服务器端身份验证附加适当的标头。结果是 401 Unauthorized Error。
相反,我需要使用 ng-click 触发下载,然后从角度控制器执行 $http.get() 请求。
HTML:
<!-- download-template.html -->
<div ng-controller="DocumentCtrl">
<a ng-click="download(document)">Download</a>
</div>
Javascript:
// DocumentCtrl.js
module.controller( "DocumentCtrl",
[ "$http", "$scope", "FileSaver", "Blob",
function( $http, $scope, FileSaver, Blob ) {
$scope.download = function( document ) {
$http.get(document.download_url, {}, { responseType: "arraybuffer" } )
.success( function( data ) {
var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" });
FileSaver.saveAs(blob, document.file_name);
});
};
}]);
FileSaver 是一个使用 Blob 保存文件的简单库(显然是在客户端上)。
这让我通过了身份验证问题,但导致文件以不可读/不可用的格式保存/下载到客户端。
为什么下载的文件格式不可用?
提前致谢。
【问题讨论】:
-
您必须使用 FileSaver 吗?你试过
window.navigator.msSaveOrOpenBlob和window.open(objectUrl)吗? -
我不需要使用 FileSaver,但使用 window.navigator.msSaveOrOpenBlob 和 window.open(objectUrl) 都会导致相同的问题:不可读的文件格式。包装/构造的文件仍然被 Blob 再次包装/构造的情况。
标签: javascript ruby-on-rails angularjs amazon-s3 oauth