I have a unique situation where my users possess private files that require downloads by authenticated users. The server I am using initially downloads a file from S3 utilizing its own set of S3 app_id and secret_token credentials. Once the file has been downloaded, it is then compiled and transmitted to the client using Rails' send_data method.
Here's how it looks in Ruby on 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
Initially, my plan was to trigger the download directly from the HTML template as shown below:
HTML:
<!-- download-template.html -->
<a target="_self" ng-href="{{ document.download_url }}" download="{{document.file_name}}">Download</a>
Although this seemed straightforward, I encountered an issue with Angular's $http interceptor not intercepting external link clicks, resulting in missing headers needed for server-side authentication. This led to a 401 Unauthorized Error.
To overcome this challenge, I decided to trigger the download using ng-click and initiating an $http.get() request from the angular controller instead.
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 is a useful library for saving files using Blobs on the client side.
This approach helped me resolve the authentication problem, but unfortunately, the downloaded file ended up being saved/downloaded in an unreadable or unusable format.
What could be causing the file to download in an unusable format?
Thank you in advance.