I'm trying to use content-disposition to force a download of a PDF and set the filename, which isn't working. In the network panel I'm seeing that the headers have been set correctly yet the PDF is opening in the browser instead of downloading, and the file name is incorrect and is just a random bunch of characters. Is there something I'm missing? I've tried in both chrome and Firefox with the same result where both show the correct headers in the network tab but the PDF only renders in the browser.
res.on('end', function() {
const body = Buffer.concat(chunks);
response.setHeader('Content-Length', body.length);
response.setHeader('Content-Type', 'application/pdf');
response.setHeader(
'Content-Disposition',
'attachment; filename="Report.pdf"',
);
response.send(body);
});
Related
I have a PDF file stored in a directory within the application (assets/pdf/fileName.pdf). I need to display it on a new tab on a button click from a dialog.
Here is what I have, after looking at various answers:
In *.component.ts:
openPDF() {
this.myService.fetchPDF().subscribe(
res => {
let file = new window.Blob([res], {type: 'application/pdf'});
let fileURL = window.URL.createObjectURL(file);
window.open(fileURL, '_blank');
}
);
}
In *.service.ts:
fetchPDF(): any {
const path = 'assets/pdf/fileName.pdf';
return this.httpClient.get(PathResolver.resolveStatic(path),{responseType : 'blob'});
}
I already tried using responseType : 'arraybuffer', but it didn't work out either.
Here are the threads I have looked at:
How to Display blob (.pdf) in an AngularJS app
Angular 2 download PDF from API and Display it in View
PDF Blob - Pop up window not showing content
Failed to load PDF document - Angular JS - BLOB
I am not sure why are you using httpClient. The outcome that you want could be simply achieved by the following code
In *.service.ts:
fetchPDF(): any {
const path = 'assets/pdf/fileName.pdf'
return path;
}
In *.component.ts:
openPDF() {
window.open(this.myService.fetchPDF(), '_blank');
}
You will either need to use the html embed tag (most likely also using a safe pipe), a PDF viewer (like Google PDF Viewer) or you can open the PDF in a new tab (this is the more common approach I see). It depends on your preference.
Succesfully i have made to Upload files into firebase storage, but now i want to display all files in table and to have option to download each file.I've read the documentation in firebase but it won't work.When i click the button which function is to get all files and the i want to visualize them in table which users can see:
Show file function:
showFileUrl(){
storageRef.child('UploadedFiles/').listAll().then(function(res) {
res.items.forEach(function(folderRef) {
console.log("folderRef",folderRef.toString());
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", "downloadURL");
xhr.responseType = "blob";
xhr.onload = function()
{
blob = xhr.response;//xhr.response is now a blob object
console.log(blob);
}
xhr.send();
});
}).catch(function(error) {
});
}
This is log of the network which i found when debugging.What i need to do to get all data and visualize it in table and to hava a download button and when is pressed to download the file
Network log:
Storage in firebase:
Blob object of the files:
Your code gets a list of all the files, but it doesn't actually to anything to read the data for each file.
When using the Web client SDK, the only way to get the data for a file is through a download URL as shown here. So you'll need to:
Loop through all the files you get back from listAll() (you're already doing this).
Call `getDownloadURL as shown here, to get a download URL for each file.
Then use another library/function (such as fetch()/XMLHTTPRequest) to read the data for each file.
Alternatively, if your files are images, you can stuff the download URL in an img tag as the preview.
I am trying to upload image to my FTP.
what i have achived so far is in this plnkr
my cordova file transfer looks like
$scope.upload =function(){
var options = {
fileKey: "file",
fileName: "gopi",
chunkedMode: false,
mimeType: "image/jpeg",
params : {'user_token':'Chandru#123', 'user_email':'wepopusers'} // directory represents remote directory, fileName represents final remote file name
};
console.log(options);
$cordovaFileTransfer.upload('ftp://308.3d8.myftpupload.com/', MyService.getImgPath(), options)
.then(function(result) {
// Success!
console.log(result);
console.log("SUCCESS: " + JSON.stringify(result.response));
alert('ftp success');
}, function(err) {
// Error
console.log(err);
alert('ftp fail');
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
console.log(progress);
});
};
My response of my error function for cordova file looks like
FileTransferError {code: 2, source: "file:///storage/sdcard0/Android/data/com.ionicframework.camera108827/cache/1462186990291.jpg", target: "ftp://308.3d8.myftpupload.com/", http_status: null, body: null…}body: nullcode: 2exception: nullhttp_status: nullsource: "file:///storage/sdcard0/Android/data/com.ionicframework.camera108827/cache/1462186990291.jpg"target: "ftp://308.3d8.myftpupload.com/"proto: Object
I have button TakePicture which will take the pic and show to the user and also I have a function to upload using cordovafiletransfer $scope.upload .
my ftp host is ftp://308.3d8.myftpupload.com/ username and password is given in my coding in this i have a folder name called gopi where my image should store.
my path of the image taken is in imageURI parameter so i used services to set the path.
steps I’m in confusion
1) I am not able to understand the var options object in cordova file transfer plugin.
2) I am not getting any erro while remote debugging but i am only invoking my error funtion in my cordova file transfer.
How can i update my taken image to FTP using IONIC
UPDATE
Thanks to gandhi's answer https://github.com/xfally/cordova-plugin-ftp some how i managed to connect to ftp without multipart.
but sill facing error in this
$window.cordova.plugin.ftp.upload("/ping", "/gopi/ping", function(percent) {
i don't know what to in the first argument and second.
$window.cordova.plugin.ftp.upload("/default.prop", "/gopi/default.prop", function(percent) {
the above line success fully posted to my ftp but i am not able to post my image which is stored in my ping variable.
https://plnkr.co/edit/ETGmdl4B0d5dlHWdJQ9m?p=info
The answer to your first question is available in the official documentation of file transfer plugin. The excerpt is as follow,
options: Optional parameters (Object). Valid keys:
fileKey: The name of the form element. Defaults to file. (DOMString)
fileName: The file name to use when saving the file on the server. Defaults to image.jpg. (DOMString)
httpMethod: The HTTP method to use - either PUT or POST. Defaults to POST. (DOMString)
mimeType: The mime type of the data to upload. Defaults to image/jpeg. (DOMString)
params: A set of optional key/value pairs to pass in the HTTP request. (Object, key/value - DOMString)
chunkedMode: Whether to upload the data in chunked streaming mode. Defaults to true. (Boolean)
headers: A map of header name/header values. Use an array to specify more than one value. On iOS, FireOS, and Android, if a header named Content-Type is present, multipart form data will NOT be used. (Object)
Check out this link for more info.
For your second question, try getting the error code in the error callback function and try to narrow down the problem.
Update: I guess ftp upload is not possible using file transfer plugin. The plugin definition itself states "The FileTransfer object provides a way to upload files using an HTTP multi-part POST or PUT request, and to download files"
You may have to look at this for ftp client for ftp uploads.
I think the title is weird but just says all i want.
I got the following API call
this.myAPI.get("/endpoint/toget/pdf/")
.then(response => {
}, function(error) {
});
The API response with a PDF file not a link but a PDF file. How do i capture that file and allow the user to ng-click and open the file?
Ideas.. Anyone?
Okay if you get a base64 string the following works perfect but sadly and obviously not in IE.
window.open("data:application/pdf;base64," + response.data.content);
I am working on meanjs application generated using https://github.com/DaftMonk/generator-angular-fullstack. I am trying to generate a .pdf file using phantomjs and download it to the browser.
The issue is that the downloaded .pdf file always shows the blank pages regardless of the number of pages. The original file on server is not corrupt. When I investigated further, found that the downloaded file is always much larger than the original file on the disk. Also this issue happens only with .pdf files. Other file types are working fine.
I've tried several methods like res.redirect('http://localhost:9000/assets/exports/receipt.pdf');, res.download('client\\assets\\exports\\receipt.pdf'),
var fileSystem = require('fs');
var stat = fileSystem.statSync('client\\assets\\exports\\receipt.pdf');
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream('client\\assets\\exports\\receipt.pdf');
return readStream.pipe(res);
and even I've tried with https://github.com/expressjs/serve-static with no changes in the result.
I am new to nodejs. What is the best way to download a .pdf file to the browser?
Update:
I am running this on a Windows 8.1 64bit Computer
I had corruption when serving static pdfs too. I tried everything suggested above. Then I found this:
https://github.com/intesso/connect-livereload/issues/39
In essence the usually excellent connect-livereload (package ~0.4.0) was corrupting the pdf.
So just get it to ignore pdfs via:
app.use(require('connect-livereload')({ignore: ['.pdf']}));
now this works:
app.use('/pdf', express.static(path.join(config.root, 'content/files')));
...great relief.
Here is a clean way to serve a file from express, and uses an attachment header to make sure the file is downloaded :
var path = require('path');
var mime = require('mime');
app.get('/download', function(req, res){
//Here do whatever you need to get your file
var filename = path.basename(file);
var mimetype = mime.lookup(file);
res.setHeader('Content-disposition', 'attachment; filename=' + filename);
res.setHeader('Content-type', mimetype);
var filestream = fs.createReadStream(file);
filestream.pipe(res);
});
There are a couple of ways to do this:
If the file is a static one like brochure, readme etc, then you can tell express that my folder has static files (and should be available directly) and keep the file there. This is done using static middleware:
app.use(express.static(pathtofile));
Here is the link: http://expressjs.com/starter/static-files.html
Now you can directly open the file using the url from the browser like:
window.open('http://localhost:9000/assets/exports/receipt.pdf');
or
res.redirect('http://localhost:9000/assets/exports/receipt.pdf');
should be working.
Second way is to read the file, the data must be coming as a buffer. Actually, it should be recognised if you send it directly, but you can try converting it to base64 encoding using:
var base64String = buf.toString('base64');
then set the content type :
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-Length': stat.size
});
and send the data as response.
I will try to put an example of this.
EDIT: You dont even need to encode it. You may try that still. But I was able to make it work without even encoding it.
Plus you also do not need to set the headers. Express does it for you. Following is the Snippet of API code written to get the pdf in case it is not public/static. You need API to serve the pdf:
router.get('/viz.pdf', function(req, res){
require('fs').readFile('viz.pdf', function(err, data){
res.send(data);
})
});
Lastly, note that the url for getting the pdf has extension pdf to it, this is for browser to recognise that the incoming file is pdf. Otherwise it will save the file without any extension.
Usually if you are using phantom to generate a pdf then the file will be written to disc and you have to supply the path and a callback to the render function.
router.get('/pdf', function(req, res){
// phantom initialization and generation logic
// supposing you have the generation code above
page.render(filePath, function (err) {
var filename = 'myFile.pdf';
res.setHeader('Content-type', "application/pdf");
fs.readFile(filePath, function (err, data) {
// if the file was readed to buffer without errors you can delete it to save space
if (err) throw err;
fs.unlink(filePath);
// send the file contents
res.send(data);
});
});
});
I don't have experience of the frameworks that you have mentioned but I would recommend using a tool like Fiddler to see what is going on. For example you may not need to add a content-length header since you are streaming and your framework does chunked transfer encoding etc.