2012-04-06 35 views
75

khung Expressjs có phương thức sendfile(). Làm thế nào tôi có thể làm điều đó mà không cần sử dụng toàn bộ khung công tác. Tôi đang sử dụng node-native-zip để tạo một kho lưu trữ và tôi muốn gửi nó cho người dùng.Nodejs gửi tệp theo phản hồi

Trả lời

119

Đây là một chương trình ví dụ sẽ gửi myfile.mp3 bằng cách phát trực tuyến từ đĩa (nghĩa là nó không đọc toàn bộ tệp vào bộ nhớ trước khi gửi tệp). Các máy chủ lắng nghe trên cổng 2000.

[Cập nhật] Như đã đề cập bởi @Aftershock trong các ý kiến, util.pump đã biến mất và được thay thế bằng một phương pháp trên nguyên mẫu Suối gọi pipe; mã dưới đây phản ánh điều này.

var http = require('http'), 
    fileSystem = require('fs'), 
    path = require('path'); 

http.createServer(function(request, response) { 
    var filePath = path.join(__dirname, 'myfile.mp3'); 
    var stat = fileSystem.statSync(filePath); 

    response.writeHead(200, { 
     'Content-Type': 'audio/mpeg', 
     'Content-Length': stat.size 
    }); 

    var readStream = fileSystem.createReadStream(filePath); 
    // We replaced all the event handlers with a simple call to readStream.pipe() 
    readStream.pipe(response); 
}) 
.listen(2000); 

Taken từ http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/

+0

Nhưng tôi không phát trực tuyến tệp từ máy chủ, tôi tạo lưu trữ – andrei

+0

Bằng "luồng", tôi có nghĩa là "gửi dữ liệu tệp tới kết nối khi được đọc" thay vì "đọc toàn bộ tệp trong bộ nhớ gửi tất cả dữ liệu đó đến kết nối cùng một lúc "(đó là cách tiếp cận ngây thơ điển hình). Tôi _don't_ có nghĩa là "truyền dữ liệu từ bộ nhớ mà không cần đĩa." Bài đăng tôi đã liên kết để giải thích chi tiết hơn. –

+0

ok bây giờ tôi nhận được nó, cảm ơn. tôi sẽ bắt đầu từ đó – andrei

3

Bạn cần sử dụng Suối gửi file (lưu trữ) trong một phản ứng, những gì là nhiều hơn bạn phải sử dụng thích hợp Content-type trong phần đầu trả lời của bạn.

Có một chức năng ví dụ mà làm điều đó:

const fs = require('fs'); 

// Where fileName is name of the file and response is Node.js Reponse. 
responseFile = (fileName, response) => { 
    const filePath = "/path/to/archive.rar" // or any file format 

    // Check if file specified by the filePath exists 
    fs.exists(filePath, function(exists){ 
     if (exists) {  
     // Content-type is very interesting part that guarantee that 
     // Web browser will handle response in an appropriate manner. 
     response.writeHead(200, { 
      "Content-Type": "application/octet-stream", 
      "Content-Disposition": "attachment; filename=" + fileName 
     }); 
     fs.createReadStream(filePath).pipe(response); 
     } else { 
     response.writeHead(400, {"Content-Type": "text/plain"}); 
     response.end("ERROR File does not exist"); 
     } 
    }); 
    } 
} 

Mục đích của trường Content-Type là để mô tả dữ liệu chứa trong cơ thể hoàn toàn đủ để user agent nhận có thể chọn một thích hợp tác nhân hoặc cơ chế để trình bày dữ liệu cho người dùng hoặc xử lý dữ liệu theo cách thích hợp.

"ứng dụng/octet-stream" được định nghĩa là "dữ liệu nhị phân tùy ý" trong RFC 2046, mục đích của loại nội dung này sẽ được lưu vào đĩa - đó là những gì bạn thực sự cần.

"filename = [name of file]" chỉ định tên tệp sẽ được tải xuống.

Để biết thêm thông tin, vui lòng xem this stackoverflow topic.

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