2015-09-07 16 views
5

Tôi muốn tải xuống tệp với trình duyệt của mình từ máy chủ đang chạy với NodeJS. Về phía server, để phục vụ các tập tin tôi có:Tải xuống tệp từ máy chủ Node.JS với AngularJS

exports.download = function(req, res) { 
    var filename = "33.jpg"; 
    var filePath = path.join(__dirname, '..', '..', 'downloads', filename); 
    var stat = fs.statSync(filePath); 

    var fileToSend = fs.readFileSync(filePath); 

    res.writeHead(200, { 
     'Content-Type': 'image/jpeg', 
     'Content-Length': stat.size, 
     'Content-Disposition': filename 
    }); 
    res.end(fileToSend); 
}; 

Các tập tin gọi là 33.jpg tồn tại và là 744KB cỡ. Các cuộc gọi từ khách hàng hoạt động tuyệt vời

Về phía khách hàng với AngularJS ở đây là làm thế nào tôi gọi một cuộc gọi bài để tải tệp (hiện tham số uri không được sử dụng):

$scope.downloadTrack = function(uri) { 
    $http.post('/api/files/download', {uri: uri}).then(function(response) { 
    var blob = new Blob([response.data], { type: 'image/jpeg' }); 
    var fileName = response.headers('content-disposition'); 
    saveAs(blob, fileName); 
    }, function(response) { 
    console.log('Download error'); 
    console.log(response); 
    }); 
} 

Các tiêu đề là ok (tôi có thể truy xuất tên tệp)

Vấn đề của tôi là tệp được tải xuống nhưng có kích thước 1,5Mb và không thể đọc được. Tôi đã thử các phương pháp khác nhau với luồng, nối dữ liệu vào phản hồi, đường ống, v.v. mà không thành công. điểm khác (không chắc chắn là quan trọng): trong vòng Safari các tập tin được mở ra với một biểu tượng bị hỏng hiển thị, trong Chrome file được lưu

PS: tôi đã tạo ra dự án với Yeoman nếu thông tin rất hữu ích

Cảm ơn tất cả

[cập nhật] phiên bản mới của chức năng máy chủ (vẫn không làm việc)

exports.download = function(req, res) { 
    var filename = "33.jpg"; 
    var filePath = path.join(__dirname, '..', '..', 'downloads', filename); 
    var stat = fs.statSync(filePath); 
    var fileToSend = fs.readFileSync(filePath); 
    res.set('Content-Type', 'image/jpeg'); 
    res.set('Content-Length', stat.size); 
    res.set('Content-Disposition', filename); 
    res.send(fileToSend); 
}; 

[Cập nhật 2] Các đôi tập tin có kích thước chứa thêm "efbffd" chuỗi char ngẫu nhiên trong file làm cho nó không thể đọc được

+0

'res.write (fileToSend); res .end(); ' – AdityaParab

+0

Kết quả tương tự. Tôi đoán vấn đề xuất phát từ phương pháp Góc hơn bên Node.JS ... –

Trả lời

6

Vấn đề giải quyết với một định nghĩa của các loại phản ứng thiết lập để Blob

$http({ 
     url: '/api/files/download', 
     method: "POST", 
     data: { 
     uri: uri 
     }, 
     responseType: 'blob' 
    }).success(function (data, status, headers, config) { 
     var blob = new Blob([data], { type: 'audio/mpeg' }); 
     var fileName = headers('content-disposition'); 
     saveAs(blob, fileName); 
    }).error(function (data, status, headers, config) { 
    console.log('Unable to download the file') 
    }); 
+0

Lỗi: saveAs không được xác định trong bảng điều khiển của tôi. làm thế nào để giải quyết –

+1

cài đặt mô-đun góc-file-saver và đặt SaveAs nhà máy như một tham số để điều khiển của bạn –

0

Bạn đang gửi người đứng đầu câu trả lời nhưng không phải là cơ thể bằng cách sử dụng res#end thay vì res#send (với một S).

exports.download = function(req, res) { 
    // ... 
    res.send(fileToSend); 
}; 

Từ Express documentation cho res#end:

Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().

+0

Cảm ơn. Tôi đã sửa (cũng là phần tiêu đề đã đặt) nhưng kết quả giống nhau: tệp nhận được hai lần kích thước so với tệp gốc và không đọc được bởi trình duyệt (và os) –

Các vấn đề liên quan