While trying to display a pdf blob on IE, I receive Access is denied error.
html file
<object ng-show="{{content}}" data="{{content}}" type="application/pdf"></object>
js file
$http.post('/api',{}, { responseType: 'arraybuffer' })
.success(function (response) {
var file = new Blob([response], { type: 'application/pdf' });
var fileUrl = window.URL.createObjectURL(file);
$scope.content = $sce.trustAsResourceUrl(fileUrl);
});
When using embed instead, acrobat pdf viewer is unable to view the temporary file.
Related
I am trying to download a zip file from a Laravel API using Angular JS. I do not believe the issue is from Laravel.
Basically when the response comes and the download trigger is made it does not know its a .zip file, however the file itself is good. But then when I manually add the .zip extension in Angular JS in the file name the browser advises its a corrupt file.
If I do not add the extension, it downloads fine, and then if i rename the file with no extension in Windows and change it to test.zip it works perfectly as a zip file. This is how I know the data is good.
I have tried arraybuffer responseType and blob. With blob I am getting the download trigger, with arraybuffer nothing is happening (including no console errors).
Here is my JS controller code:
vm.downloadSelectedFiles = function() {
vm.selectedFiles = [];
angular.forEach(vm.fileDownloadList, function(value,index) {
if(value==1) {
vm.selectedFiles.push(index);
}
});
Data.downloadSelectedFiles(vm.selectedFiles,vm.stationIDToLookUp)
.then(function (data) {
var url = $window.URL || $window.webkitURL;
vm.fileUrl = url.createObjectURL(data.data);
var a = document.createElement("a");
a.href = vm.fileUrl;
a.download = 'test.zip';
//a.download = 'test';
a.click();
}).catch(function (err) {
});
}
Here is my JS service code
downloadSelectedFiles: function downloadSelectedFiles(selectedFiles,stationID) {
var apiBase = apiUrl + 'download-selected-files';
var config = {
//responseType: 'arraybuffer'
responseType: 'blob'
};
var data = {
selectedFiles: selectedFiles,
stationID: stationID
}
return $http.post(apiBase, data, config);
}
And just in case there is something relevant about the response from the API. Here is my Laravel code
public function downloadSelectedFiles(PublishDataRequest $requestData) {
return response()->file(storage_path() . '/app/files/test.zip');
}
Try setting the MIME type to application/zip:
Data.downloadSelectedFiles(vm.selectedFiles,vm.stationIDToLookUp)
.then(function (response) {
var blob = response.data;
var zipBlob = new Blob([blob], { type: "application/zip" });
var url = $window.URL || $window.webkitURL;
vm.fileUrl = url.createObjectURL(zipBlob);
var a = document.createElement("a");
a.href = vm.fileUrl;
a.download = 'test.zip';
//a.download = 'test';
a.click();
}).catch(function (response) {
console.log("ERROR", response);
throw response;
});
Angular client code:
$http.post('/zip', {
id: _id
})
.success(function (data, status, headers, config) {
var blob = new Blob([data], {type: "application/zip"});
var contentDisp = headers('content-disposition');
if (contentDisp && /^attachment/i.test(contentDisp)) {
var fileName = contentDisp.toLowerCase()
.split('filename=')[1]
.split(';')[0]
.replace(/"/g, '');
//The below command works but generates a corrupt zip file.
FileSaver.saveAs(blob, fileName);
}
})
.error(function () {
console.log("Could not download");
});
NodeJS Server Code:
app.route('/zip/')
.post(function(req, res) {
var output = fs.createWriteStream(join(outdir, outzipfile));
//Using s3zip to archive.
s3Zip
.archive({ s3: s3Client, bucket: bucket}, folder, s3_files)
.pipe(output);
output.on('close', function() {
//This sends back a zip file.
res.download(outPutDirectory + outputBcemFile);
});
output.on('error', function(err) {
console.log(err);
return res.status(500).json({error: "Internal Server Error"});
});
});
Although FileSaver.saveAs works and downloads the zip file, it seems to be corrupted. Is the type "application/zip" correct? I have also tried "octet/stream" and it downloads a corrupt zip file too. Any help would be highly invaluable! Thanks.
This is a bug mentioned in Git in below link :
https://github.com/eligrey/FileSaver.js/issues/156
To solve you need to add : responseType: 'arraybuffer' to your $http Request headers and it will work.
i am trying to open a pdf file in angularjs.actually i created a pdf file with database content and stored in the server location now i need to open a pdf file in the browser.I tried the bellow code.but not worked.
controller.js
$http.get(urlBase+'/generatePdfUrl')
.success(function (data) { // data is your url
var file = new Blob([data], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
$window.open(fileURL);
}).error(function(data){
alert(data);
});
I am getting my file URL correctly in data.but new tab open in the browser shows the below URL in browser address bar
blob:http://localhost:8080/c87ffb9f-b2cb-8741-a2d2-3c8af5609359
can any one help me to do this
$http.get(urlBase+'/generatePdfUrl').then(function(data){
$window.open(data);
});
I am unable to save this content as proper PDF using FileSaver.js
this is Angular code
$http(
{ url:root.api_root+'/appointments/generatePDF/'+$routeParams.id,
method:'GET'
}).then(function(res){ //
$log.log(res.data);
var blob = new Blob([res.data], { type: 'application/pdf' });
window.open(res.data);
// saveAs(blob, 'file.pdf');
});
this is TCPDF Backend code
$pdf->Output("php://output", 'F');
echo file_get_contents("php://output");
When downloading binary data such as PDF files, it is important to set the responseType property:
$http(
{ url:root.api_root+'/appointments/generatePDF/'+$routeParams.id,
method:'GET',
//IMPORTANT
responseType: 'blob'
}).then(function(res){ //
$log.log(res.data);
//var blob = new Blob([res.data], { type: 'application/pdf' });
//window.open(res.data);
var blob = res.data;
saveAs(blob, 'file.pdf');
});
If the responseType property is omitted, the XHR API defaults to processing the data as UTF-8 text. The process of decoding the data as UTF-8 text will corrupt binary files such as PDF or images.
For more information, see MDN Web API Reference - XHR ResponseType
Dependencies
AngularJS
FileSaver.js
Blob.js
Installation
Using bower: bower install angular-file-saver
Using npm: npm install angular-file-saver
Basic usage
Include ngFileSaver module into your project;
Pass both FileSaver and Blob services as dependencies;
Create a Blob object by
passing an array with data as the first argument and an object with set of options
as the second one: new Blob(['text'], { type: 'text/plain;charset=utf-8' });
Invoke FileSaver.saveAs with the following arguments:
data Blob: a Blob instance;
filename String: a custom filename (an extension is optional);
disableAutoBOM Boolean: (optional) Disable automatically provided Unicode text encoding hints.
You can do so by injecting FileSaver and Blob into the controller and then using the syntax as shown below:
angular.module('sample',['ngFileSaver'])
.controller('ConsultationDetailsController', ['$scope', 'FileSaver', 'Blob', function($scope, FileSaver, Blob){
$scope.download = function (fileName) {
$scope.isLoading = true;
downloadHttpService.getDocument(fileName)
.then(function (response) {
var data = response.data;
var status = response.status;
var header = response.headers();
var fileType = header['content-type'];
var blob = new Blob([data], { type: fileType });
FileSaver.saveAs(blob, originalFileName);
})
.catch(function (resp) {
// show error
})
.finally(function (data) {
// execute finally block.
});
};
}]);
if you want only the pdf type then you can hard coded define
fileType as 'application/pdf' like this var fileType= 'application/pdf';
Hope this solves your problem :)
Its work for me. Just try it.
$http(
{ url:root.api_root+'/appointments/generatePDF/'+$routeParams.id,
method:'GET'
}).then(function(res){
$log.log(res.data);
saveAs('data:application/pdf;base64,' + res.data, 'file.pdf');
});
I was wondering how I can save a file that is contained in a response from the server in angular ? (So that the file is automatically downloaded when the response arrives)
Edit :
I have a $http post method, and I get pdf data in the response. On success, I want to save the response data as a pdf file.
E. g :
$http({
method: 'POST',
url : 'theUrl',
data: //some array that is received
headers : //content type info
}
.success(function(response) { // I want to save the response as a pdf });
On angular 2... you can do:
import { saveAs } from 'browser-filesaver/FileSaver.js'
downloadFile(data: Response) {
var blob = new Blob([data], {type: 'application/x-tar'});
saveAs(blob, "report.tgz");
}
Using HTML5 FileSaver interface, this can be achieved:
https://github.com/eligrey/FileSaver.js/
Example solution:
//Call API to retrieve file stream using POST request
$http.post("URL", searchData, { responseType: 'arraybuffer' }).then(
response => {
//Download file from response
saveFileAs(response);
},
data => {
//raise error
}
);
function saveFileAs(response) {
var contentDisposition = response.headers("content-disposition");
//Retrieve file name from content-disposition
var fileName = contentDisposition.substr(contentDisposition.indexOf("filename=") + 9);
fileName = fileName.replace(/\"/g, "");
var contentType = response.headers("content-type");
var blob = new Blob([response.data], { type: contentType });
saveAs(blob, fileName);
}
You can't save the document as you don't have access to the users file system in a browser. You could send the URL of the pdf back, then trigger the browsers build in file save / open mechanism by adding a dummy iFrame to the body:
$http({
method: 'POST',
url : 'theUrl',
data: //some array that is received
headers : //content type info
}
.success(function (data) {
if ($('#iframe').length == 0) {
var $iframe = $('<iframe id="iframe" style="display: none"></iframe>');
$('body').append($iframe);
}
$('#iframe').attr('src', {{url to retrieve the file}})
})