0

I've read lots of answers tried many snippets but I can't solve my problem.

I've a web application created in Angular and backend application written in node.js with express framework.

User is able to upload a file to that application and this file is saved in directory that isn't available from public.

The another feature of that application is possibility to download that uploaded file by user. And here my issue starts.

I'll show some code, either from frontend application annd from backend.

Controller:

$scope.getAttachment = function (fileName) {
    return attachmentService.getAttachment({
            fileName: fileName
        }).then(function (data, status, headers, config) {
            var element = angular.element('<a/>');
            element.attr({
                href: 'data:application/pdf,' + encodeURIComponent(data),
                target: '_blank',
                download: fileName
            })[0].click();
        });
    };

Service:

getAttachment: function (req) {
    return $http.get('/attachment/' + req.fileName);
}

First of all is there any way to get information about requested file mime type? All those parameters status, headers and config are undefined.

Backend:

function (req, res) {
    logger.trace('Getting attachment ' + req.param('fileName'));
    async.waterfall([
            function (cb) {
                attachmentService.getAttachment(req.param('fileName'), cb);
            }
        ], function (err, filePath) {
            if (err) {
                logger.error(util.inspect(err));
                res.status(404).json({message: err.code});
            } else {
                res.status(200).attachment(filePath).sendFile(filePath, {
                    root: path.join(__dirname, '..', '..')
                });
            }
        }
    );
});

This solution works for example with TXT files but images are corrupted (can't be opened), PDFs are without content but can be opened.

Here are response headers:

Accept-Ranges:bytes
Cache-Control:public, max-age=0
Connection:keep-alive
Date:Mon, 10 Nov 2014 10:19:13 GMT
ETag:W/"1a-3292258531"
Last-Modified:Mon, 10 Nov 2014 09:57:26 GMT
X-Powered-By:Express

I've changed backend implementation to use res.download method from express framework:

res.download(filePath, req.param('fileName'), function (err) {
    if (err) {

    }
});

After that I've noticed that error is thrown with title 'Request aborted' and code 'ECONNABORT'. Why?

Bananan
  • 613
  • 5
  • 19
  • First of all I'd check headers of both request and header if they contain correct name and content length Maybe you can find a solution here: http://stackoverflow.com/questions/7288814/download-a-file-from-nodejs-server-using-express – maurycy Nov 10 '14 at 09:47
  • I've checked console output and there aren't any headers with content of downloaded file... But response data looks OK, and length of response is the same as file size on disk. I've added them to initial post. – Bananan Nov 10 '14 at 10:21
  • Did you checked solution on link suggested by me in previous comment? – maurycy Nov 10 '14 at 22:17
  • @maurycy, yes I've used `res.download` function as @loganfsmyth proposed in first answer in question linked by you. Downloading of CSV or TXT files works well but images or PDFs e.g. are still broken. Images can't be opened, PDFs can be opened, have proper page count but every page is empty... – Bananan Nov 10 '14 at 23:29
  • It seems that something wrong happens to file data encoding during passing to from server to client. – Bananan Nov 11 '14 at 00:54
  • I cannot hurt to define the Data URI as "data:application/pdf;base64," to further enforce the content type. – Heikki Nov 11 '14 at 20:32

0 Answers0