Nodejs gửi tệp để phản hồi


113

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

Câu trả lời:


183

Đây là một chương trình ví dụ sẽ gửi myfile.mp3 bằng cách truyền trực tuyến 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). Máy chủ lắng nghe trên cổng 2000.

[Cập nhật] Như đã đề cập bởi @Aftershock trong các nhận xét, util.pumpđã biến mất và được thay thế bằng một phương thức trên nguyên mẫu Luồng được gọi là 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);

Lấy từ http://elegantcode.com/2011/04/06/aking-baby-steps-with-node-js-pumping-data-between-streams/


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

Theo "stream", ý tôi là "gửi dữ liệu tệp đến kết nối khi nó đang được đọc" trái ngược với "đọc toàn bộ tệp trong bộ nhớ rồi 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 không phải là "truyền dữ liệu từ bộ nhớ mà không cần chuyển vào đĩa." Bài đăng tôi đã liên kết để giải thích chi tiết hơn.
Michelle Tilley

6
use.pump (readStream, phản hồi); được khấu hao ... sử dụng readStream.pipe (response);
Dư chấn


@Abdul Không chắc tôi hiểu câu hỏi của bạn; muốn gửi cho tôi một email ?
Michelle Tilley

13

Bạn cần sử dụng Luồng để gửi tệp (lưu trữ) trong một phản hồi, bạn còn phải sử dụng Loại nội dung thích hợp trong tiêu đề phản hồi của mình.

Có một ví dụ về chức năng 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 Loại-Nội dung là mô tả đầy đủ dữ liệu có trong phần thân để tác nhân người dùng nhận có thể chọn một tác nhân hoặc cơ chế thích hợp để hiển thị dữ liệu cho người dùng hoặc xử lý dữ liệu theo cách thích hợp.

"application / 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 là được lưu vào đĩa - đó là thứ bạn thực sự cần.

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

Để biết thêm thông tin, vui lòng xem chủ đề stackoverflow này .


cách yêu cầu cuộc gọi ở phía máy khách cung cấp mã phía máy khách
ashwini 15/10/18

1
xin lưu ý rằng chức năng 'tồn tại' không được dùng nữa.
Ievgen Naida
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.