Cách phục vụ hình ảnh bằng cách sử dụng nodejs


147

Tôi có một logo đang cư trú tại nơi công cộng / hình ảnh / logo.gif. Đây là mã nodejs của tôi.

http.createServer(function(req, res){
  res.writeHead(200, {'Content-Type': 'text/plain' });
  res.end('Hello World \n');
}).listen(8080, '127.0.0.1');

Nó hoạt động nhưng khi tôi yêu cầu localhost: 8080 / logo.gif thì rõ ràng tôi không nhận được logo.

Những thay đổi tôi cần làm để phục vụ một hình ảnh.

Câu trả lời:


224

Cập nhật năm 2016

Ví dụ với Express và không có Express thực sự hoạt động

Câu hỏi này đã hơn 5 tuổi nhưng mỗi câu trả lời đều có một số vấn đề .

TL; DR

Cuộn xuống để lấy ví dụ để phục vụ một hình ảnh với:

  1. express.static
  2. express
  3. connect
  4. http
  5. net

Tất cả các ví dụ cũng có trên GitHub: https://github.com/rsp/node-static-http-servers

Kết quả kiểm tra có sẵn trên Travis: https://travis-ci.org/rsp/node-static-http-servers

Giới thiệu

Sau hơn 5 năm kể từ khi câu hỏi này được hỏi, chỉ có một câu trả lời đúng bởi Generalhenry nhưng mặc dù câu trả lời đó không có vấn đề gì với mã, nó dường như có một số vấn đề với việc tiếp nhận . Nó đã được nhận xét rằng nó "không giải thích nhiều ngoài việc làm thế nào để dựa vào người khác để hoàn thành công việc" và thực tế có bao nhiêu người đã bỏ phiếu nhận xét này cho thấy rõ ràng rất nhiều điều cần làm rõ.

Trước hết, một câu trả lời hay cho "Cách phục vụ hình ảnh bằng Node.js" không phải là triển khai một máy chủ tệp tĩnh từ đầu và làm điều đó không tốt. Một câu trả lời tốt là sử dụng một mô-đun như Express thực hiện công việc một cách chính xác .

Trả lời các bình luận nói rằng sử dụng Express "không giải thích gì nhiều ngoài cách dựa vào người khác để hoàn thành công việc" cần lưu ý rằng việc sử dụng httpmô-đun đã dựa vào người khác để hoàn thành công việc. Nếu ai đó không muốn dựa vào bất kỳ ai để hoàn thành công việc thì ít nhất nên sử dụng ổ cắm TCP thô - điều mà tôi làm trong một ví dụ dưới đây.

Một vấn đề nghiêm trọng hơn là tất cả các câu trả lời ở đây sử dụng httpmô-đun đều bị hỏng . Họ đưa ra các điều kiện chủng tộc , độ phân giải đường dẫn không an toàn sẽ dẫn đến lỗ hổng truyền tải đường dẫn , chặn I / O sẽ hoàn toàn không phục vụ bất kỳ yêu cầu đồng thời nào và các vấn đề tế nhị khác - chúng hoàn toàn bị phá vỡ như những ví dụ về câu hỏi và Tuy nhiên, họ đã sử dụng tính trừu tượng được cung cấp bởi httpmô-đun thay vì sử dụng ổ cắm TCP để họ thậm chí không làm mọi thứ từ đầu như họ yêu cầu.

Nếu câu hỏi là "Làm thế nào để triển khai máy chủ tệp tĩnh từ đầu, như một bài tập học tập" thì bằng mọi cách, câu trả lời làm thế nào để làm điều đó nên được đăng - nhưng ngay cả khi đó chúng ta nên mong đợi chúng ít nhất là chính xác . Ngoài ra, không phải là không có lý khi cho rằng ai đó muốn phục vụ hình ảnh có thể muốn phục vụ nhiều hình ảnh hơn trong tương lai nên người ta có thể lập luận rằng việc viết một máy chủ tệp tĩnh tùy chỉnh cụ thể chỉ có thể phục vụ một tệp duy nhất với đường dẫn được mã hóa cứng là hơi thiển cận. Khó có thể tưởng tượng rằng bất kỳ ai tìm kiếm câu trả lời về cách phục vụ hình ảnh sẽ hài lòng với một giải pháp chỉ phục vụ một hình ảnh thay vì một giải pháp chung để phục vụ bất kỳ hình ảnh nào.

Nói tóm lại, câu hỏi là làm thế nào để phục vụ một hình ảnh và một câu trả lời cho điều đó là sử dụng một mô-đun thích hợp để thực hiện điều đó một cách an toàn, phù hợp và đáng tin cậy , có thể đọc được, có thể duy trì và trong tương lai trong khi sử dụng Node chuyên nghiệp tốt nhất phát triển. Nhưng tôi đồng ý rằng một bổ sung tuyệt vời cho câu trả lời như vậy sẽ chỉ ra một cách để thực hiện chức năng tương tự bằng tay nhưng thật đáng buồn là mọi nỗ lực để làm điều đó đã thất bại cho đến nay. Và đó là lý do tại sao tôi viết một số ví dụ mới.

Sau phần giới thiệu ngắn này, đây là năm ví dụ của tôi thực hiện công việc trên 5 mức độ trừu tượng khác nhau.

Chức năng tối thiểu

Mỗi ví dụ phục vụ các tệp từ publicthư mục và hỗ trợ chức năng tối thiểu của:

  • Các loại MIME cho hầu hết các tệp phổ biến
  • phục vụ HTML, JS, CSS, văn bản và hình ảnh đơn giản
  • phục vụ index.htmlnhư một chỉ mục thư mục mặc định
  • phản hồi với mã lỗi cho các tập tin bị thiếu
  • không có lỗ hổng truyền tải
  • không có điều kiện cuộc đua trong khi đọc các tập tin

Tôi đã thử nghiệm mọi phiên bản trên Node phiên bản 4, 5, 6 và 7.

express.static

Phiên bản này sử dụng express.staticphần mềm trung gian tích hợp của expressmô-đun.

Ví dụ này có nhiều chức năng nhất và số lượng mã ít nhất.

var path = require('path');
var express = require('express');
var app = express();

var dir = path.join(__dirname, 'public');

app.use(express.static(dir));

app.listen(3000, function () {
    console.log('Listening on http://localhost:3000/');
});

express

Phiên bản này sử dụng expressmô-đun nhưng không có express.staticphần mềm trung gian. Phục vụ các tệp tĩnh được triển khai như một trình xử lý tuyến đường duy nhất bằng cách sử dụng các luồng.

Ví dụ này có các biện pháp đối phó đường dẫn đơn giản và hỗ trợ một tập hợp hạn chế các loại MIME phổ biến nhất.

var path = require('path');
var express = require('express');
var app = express();
var fs = require('fs');

var dir = path.join(__dirname, 'public');

var mime = {
    html: 'text/html',
    txt: 'text/plain',
    css: 'text/css',
    gif: 'image/gif',
    jpg: 'image/jpeg',
    png: 'image/png',
    svg: 'image/svg+xml',
    js: 'application/javascript'
};

app.get('*', function (req, res) {
    var file = path.join(dir, req.path.replace(/\/$/, '/index.html'));
    if (file.indexOf(dir + path.sep) !== 0) {
        return res.status(403).end('Forbidden');
    }
    var type = mime[path.extname(file).slice(1)] || 'text/plain';
    var s = fs.createReadStream(file);
    s.on('open', function () {
        res.set('Content-Type', type);
        s.pipe(res);
    });
    s.on('error', function () {
        res.set('Content-Type', 'text/plain');
        res.status(404).end('Not found');
    });
});

app.listen(3000, function () {
    console.log('Listening on http://localhost:3000/');
});

connect

Phiên bản này sử dụng connectmô-đun một mức độ trừu tượng thấp hơn express.

Ví dụ này có chức năng tương tự như expressphiên bản nhưng sử dụng API đòn bẩy thấp hơn một chút.

var path = require('path');
var connect = require('connect');
var app = connect();
var fs = require('fs');

var dir = path.join(__dirname, 'public');

var mime = {
    html: 'text/html',
    txt: 'text/plain',
    css: 'text/css',
    gif: 'image/gif',
    jpg: 'image/jpeg',
    png: 'image/png',
    svg: 'image/svg+xml',
    js: 'application/javascript'
};

app.use(function (req, res) {
    var reqpath = req.url.toString().split('?')[0];
    if (req.method !== 'GET') {
        res.statusCode = 501;
        res.setHeader('Content-Type', 'text/plain');
        return res.end('Method not implemented');
    }
    var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
    if (file.indexOf(dir + path.sep) !== 0) {
        res.statusCode = 403;
        res.setHeader('Content-Type', 'text/plain');
        return res.end('Forbidden');
    }
    var type = mime[path.extname(file).slice(1)] || 'text/plain';
    var s = fs.createReadStream(file);
    s.on('open', function () {
        res.setHeader('Content-Type', type);
        s.pipe(res);
    });
    s.on('error', function () {
        res.setHeader('Content-Type', 'text/plain');
        res.statusCode = 404;
        res.end('Not found');
    });
});

app.listen(3000, function () {
    console.log('Listening on http://localhost:3000/');
});

http

Phiên bản này sử dụng httpmô-đun là API cấp thấp nhất cho HTTP trong Nút.

Ví dụ này có chức năng tương tự như connectphiên bản nhưng sử dụng các API cấp thấp hơn.

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

var dir = path.join(__dirname, 'public');

var mime = {
    html: 'text/html',
    txt: 'text/plain',
    css: 'text/css',
    gif: 'image/gif',
    jpg: 'image/jpeg',
    png: 'image/png',
    svg: 'image/svg+xml',
    js: 'application/javascript'
};

var server = http.createServer(function (req, res) {
    var reqpath = req.url.toString().split('?')[0];
    if (req.method !== 'GET') {
        res.statusCode = 501;
        res.setHeader('Content-Type', 'text/plain');
        return res.end('Method not implemented');
    }
    var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
    if (file.indexOf(dir + path.sep) !== 0) {
        res.statusCode = 403;
        res.setHeader('Content-Type', 'text/plain');
        return res.end('Forbidden');
    }
    var type = mime[path.extname(file).slice(1)] || 'text/plain';
    var s = fs.createReadStream(file);
    s.on('open', function () {
        res.setHeader('Content-Type', type);
        s.pipe(res);
    });
    s.on('error', function () {
        res.setHeader('Content-Type', 'text/plain');
        res.statusCode = 404;
        res.end('Not found');
    });
});

server.listen(3000, function () {
    console.log('Listening on http://localhost:3000/');
});

net

Phiên bản này sử dụng netmô-đun là API cấp thấp nhất cho các socket TCP trong Node.

Ví dụ này có một số chức năng của httpphiên bản nhưng giao thức HTTP tối thiểu và không đầy đủ đã được triển khai từ đầu. Vì nó không hỗ trợ mã hóa khối, nó tải các tệp vào bộ nhớ trước khi phục vụ chúng để biết kích thước trước khi gửi phản hồi vì việc lưu trữ các tệp và sau đó tải sẽ đưa ra một điều kiện cuộc đua.

var path = require('path');
var net = require('net');
var fs = require('fs');

var dir = path.join(__dirname, 'public');

var mime = {
    html: 'text/html',
    txt: 'text/plain',
    css: 'text/css',
    gif: 'image/gif',
    jpg: 'image/jpeg',
    png: 'image/png',
    svg: 'image/svg+xml',
    js: 'application/javascript'
};

var server = net.createServer(function (con) {
    var input = '';
    con.on('data', function (data) {
        input += data;
        if (input.match(/\n\r?\n\r?/)) {
            var line = input.split(/\n/)[0].split(' ');
            var method = line[0], url = line[1], pro = line[2];
            var reqpath = url.toString().split('?')[0];
            if (method !== 'GET') {
                var body = 'Method not implemented';
                con.write('HTTP/1.1 501 Not Implemented\n');
                con.write('Content-Type: text/plain\n');
                con.write('Content-Length: '+body.length+'\n\n');
                con.write(body);
                con.destroy();
                return;
            }
            var file = path.join(dir, reqpath.replace(/\/$/, '/index.html'));
            if (file.indexOf(dir + path.sep) !== 0) {
                var body = 'Forbidden';
                con.write('HTTP/1.1 403 Forbidden\n');
                con.write('Content-Type: text/plain\n');
                con.write('Content-Length: '+body.length+'\n\n');
                con.write(body);
                con.destroy();
                return;
            }
            var type = mime[path.extname(file).slice(1)] || 'text/plain';
            var s = fs.readFile(file, function (err, data) {
                if (err) {
                    var body = 'Not Found';
                    con.write('HTTP/1.1 404 Not Found\n');
                    con.write('Content-Type: text/plain\n');
                    con.write('Content-Length: '+body.length+'\n\n');
                    con.write(body);
                    con.destroy();
                } else {
                    con.write('HTTP/1.1 200 OK\n');
                    con.write('Content-Type: '+type+'\n');
                    con.write('Content-Length: '+data.byteLength+'\n\n');
                    con.write(data);
                    con.destroy();
                }
            });
        }
    });
});

server.listen(3000, function () {
    console.log('Listening on http://localhost:3000/');
});

Tải ví dụ

Tôi đã đăng tất cả các ví dụ trên GitHub với nhiều lời giải thích hơn.

Ví dụ với express.static, express, connect, httpnet:

Dự án khác chỉ sử dụng express.static:

Xét nghiệm

Kết quả kiểm tra có sẵn trên Travis:

Mọi thứ đều được thử nghiệm trên các phiên bản Node 4, 5, 6 và 7.

Xem thêm

Các câu trả lời liên quan khác:


8
Câu trả lời hay nhất cho câu hỏi Quá tệ, tôi có thể nâng cấp bạn chỉ một lần.
Kulvar

3
Nên có một cách để tân trang những câu hỏi cổ điển như thế này! Tôi chỉ lãng phí một giờ hoặc lâu hơn để cố gắng để có được phản hồi 110 phiếu để làm việc. Cuối cùng tôi cuộn xuống chỉ để kiểm tra. Câu trả lời của bạn có thể (nên) là một cuốn sách giáo khoa về chủ đề này.
Thái Lan

2
Câu trả lời hay nhất và chi tiết đầy đủ. Nên được đánh dấu câu trả lời được chấp nhận. Cảm ơn bạn đời !!!
Mitchodh M

Tôi không biết tại sao mọi người sẽ sử dụng Express. Tôi đã làm quá ngay từ đầu có lẽ vì những người khác đã làm. Sau đó, tôi nhận ra rằng sử dụng mô-đun http của Node là cách tiếp cận phù hợp. Đó là những gì nó được cung cấp cho. Bạn có được rất nhiều sự linh hoạt. Bạn hiểu giao thức HTTP và bạn có thể gỡ lỗi dễ dàng. Express cung cấp rất nhiều biệt ngữ và một lớp mỏng trên mô-đun http, dễ thực hiện với mã hóa thô với mô-đun http. Tôi thực sự khuyên mọi người dùng Express hoặc bất kỳ mô-đun nào khác tránh xa họ và sử dụng mô-đun http trực tiếp.
Nắng

1
một lưu ý tôi muốn đề cập cho những người mới như tôi: khi chúng tôi khai báo một thư mục là tĩnh bằng cách sử dụng express.staticchúng tôi có thể tìm nạp hình ảnh bằng cách gọi url http://ip:port/path_after_the_static_folder, chúng tôi không cần đề cập đến chính thư mục tĩnh để phục vụ hình ảnh. Mặc dù chúng tôi có thể thêm điều đó bằng cách sử dụng app.use('/static', express.static(imagePath))để thuận tiện làm tài liệu mệnh giá trong: expressjs.com/en/starter/static-files.html
Rakibul Haq

160

Tôi đồng ý với các áp phích khác rằng cuối cùng, bạn nên sử dụng một khung, chẳng hạn như Express .. nhưng trước tiên bạn cũng nên hiểu cách làm một cái gì đó cơ bản như thế này mà không cần thư viện, để thực sự hiểu thư viện tóm tắt gì cho bạn .. các bước là

  1. Phân tích yêu cầu HTTP đến, để xem người dùng đang yêu cầu đường dẫn nào
  2. Thêm một đường dẫn trong câu lệnh có điều kiện để máy chủ phản hồi
  3. Nếu hình ảnh được yêu cầu, đọc tệp hình ảnh từ đĩa.
  4. Phục vụ loại nội dung hình ảnh trong một tiêu đề
  5. Phục vụ nội dung hình ảnh trong cơ thể

Mã sẽ trông giống như thế này (không được kiểm tra)

fs = require('fs');
http = require('http');
url = require('url');


http.createServer(function(req, res){
  var request = url.parse(req.url, true);
  var action = request.pathname;

  if (action == '/logo.gif') {
     var img = fs.readFileSync('./logo.gif');
     res.writeHead(200, {'Content-Type': 'image/gif' });
     res.end(img, 'binary');
  } else { 
     res.writeHead(200, {'Content-Type': 'text/plain' });
     res.end('Hello World \n');
  }
}).listen(8080, '127.0.0.1');

27
Bạn không nên sử dụng readFileSync ở giữa phản hồi. Nên sử dụng tải đồng bộ trên tic đầu tiên hoặc phương thức async. codr.cc/s/5d0b73d6/js
generalhenry

1
Mặc dù vậy, tôi đã đồng ý với bạn về phiên bản đồng bộ hóa, đối với phiên bản async, tôi nghĩ rằng sự nguy hiểm của việc sử dụng các thao tác không chặn cho các tệp là nó có thể gửi phản hồi trước khi toàn bộ tệp được đọc và cuối cùng để lại cho bạn với một phần tập tin được phục vụ cho người dùng? Bạn có cần sử dụng mã hóa chunked nếu bạn sử dụng tệp async đọc không?
noli

1
fs.readFileSync không gọi lại cho đến khi toàn bộ tệp được tải nên không cần xử lý khối. Xử lý khối chủ yếu là để chuyển tập tin mạng (vì mọi thứ có thể mất nhiều thời gian hơn dự kiến).
Generalhenry

9
Các dòng res.end(img);nên được res.end(img, 'binary');. Làm tốt lắm!
Honza Pokorny

3
+1 cho "nhưng trước tiên bạn cũng nên hiểu cách làm một cái gì đó cơ bản như thế này mà không cần thư viện, để thực sự hiểu thư viện tóm tắt gì cho bạn .."
Sunny

67

Bạn nên sử dụng khung thể hiện .

npm install express

và sau đó

var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080);

và sau đó URL localhost: 8080 / hình ảnh / logo.gif sẽ hoạt động.


18
An toàn, nhưng không giải thích gì nhiều ngoài cách dựa vào người khác để hoàn thành công việc.
LeeGee

Tôi đã thêm một phiên bản nút vanilla (chỉ các mô-đun lõi).
generalhenry

+ Tôi Đây là câu trả lời đúng duy nhất được đăng cho đến nay. Tôi giải thích nó trong câu trả lời của tôi chi tiết hơn.
rsp

15

Quá muộn nhưng giúp được ai đó, tôi đang sử dụng node version v7.9.0express version 4.15.0

nếu cấu trúc thư mục của bạn là một cái gì đó như thế này:

your-project
   uploads
   package.json
   server.js

mã server.js:

var express         = require('express');
var app             = express();
app.use(express.static(__dirname + '/uploads'));// you can access image 
 //using this url: http://localhost:7000/abc.jpg
//make sure `abc.jpg` is present in `uploads` dir.

//Or you can change the directory for hiding real directory name:

`app.use('/images', express.static(__dirname+'/uploads/'));// you can access image using this url: http://localhost:7000/images/abc.jpg


app.listen(7000);

14

Phiên bản nút vani theo yêu cầu:

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');

http.createServer(function(req, res) {
  // parse url
  var request = url.parse(req.url, true);
  var action = request.pathname;
  // disallow non get requests
  if (req.method !== 'GET') {
    res.writeHead(405, {'Content-Type': 'text/plain' });
    res.end('405 Method Not Allowed');
    return;
  }
  // routes
  if (action === '/') {
    res.writeHead(200, {'Content-Type': 'text/plain' });
    res.end('Hello World \n');
    return;
  }
  // static (note not safe, use a module for anything serious)
  var filePath = path.join(__dirname, action).split('%20').join(' ');
  fs.exists(filePath, function (exists) {
    if (!exists) {
       // 404 missing files
       res.writeHead(404, {'Content-Type': 'text/plain' });
       res.end('404 Not Found');
       return;
    }
    // set the content type
    var ext = path.extname(action);
    var contentType = 'text/plain';
    if (ext === '.gif') {
       contentType = 'image/gif'
    }
    res.writeHead(200, {'Content-Type': contentType });
    // stream the file
    fs.createReadStream(filePath, 'utf-8').pipe(res);
  });
}).listen(8080, '127.0.0.1');

2
Bạn không muốn kiểm tra fs.exists(điều kiện cuộc đua), đó là một thói quen tốt hơn để bắt lỗi khi đường ống.
Brendan

Mặc dù kiểm tra tồn tại trong trường hợp này không phải là cách nút, nhưng mọi thứ khác về câu trả lời này tốt hơn 1 triệu lần so với câu trả lời được chấp nhận.
Ninjaxor

1
Tôi đồng ý với @BrendanAshworth. Các điều kiện cuộc đua có mặt trong hầu hết các câu trả lời ở đây. Tôi đã viết nhiều hơn về nó trong câu trả lời của tôi . Nhưng Kudos đã viết nó với các luồng. Hầu như tất cả các câu trả lời khác đều sử dụng readFileSync đang chặn và không nên được sử dụng trong bất kỳ trình xử lý sự kiện nào.
rsp

1
var filePath = path.resolve ('công khai', '.' + phần.pathname); answer.writeHead (200, {'Kiểu nội dung': mime.lookup (part.pathname)}); mime - gói mime-type từ npm
Rijen

14

var http = require('http');
var fs = require('fs');

http.createServer(function(req, res) {
  res.writeHead(200,{'content-type':'image/jpg'});
  fs.createReadStream('./image/demo.jpg').pipe(res);
}).listen(3000);
console.log('server running at 3000');

đơn giản và đến mức, cách tốt hơn so với câu trả lời rõ ràng .. điều này xứng đáng 1000 upvote. Chỉ là một mẹo: có thể xóa đoạn mã và thay thế nó bằng văn bản javascript
bluejayke

có thể truyền tham số để './image/:jpg có thể phục vụ bất kỳ hình ảnh nào không?
Prav

13

Tôi thích sử dụng Restify cho các dịch vụ REST. Trong trường hợp của tôi, tôi đã tạo một dịch vụ REST để phục vụ hình ảnh và sau đó nếu một nguồn hình ảnh trả về 404/403, tôi muốn trả về một hình ảnh thay thế. Đây là những gì tôi nghĩ ra khi kết hợp một số thứ ở đây:

function processRequest(req, res, next, url) {
    var httpOptions = {
        hostname: host,
        path: url,
        port: port,
        method: 'GET'
    };

    var reqGet = http.request(httpOptions, function (response) {
        var statusCode = response.statusCode;

        // Many images come back as 404/403 so check explicitly
        if (statusCode === 404 || statusCode === 403) {
            // Send default image if error
            var file = 'img/user.png';
            fs.stat(file, function (err, stat) {
                var img = fs.readFileSync(file);
                res.contentType = 'image/png';
                res.contentLength = stat.size;
                res.end(img, 'binary');
            });

        } else {
            var idx = 0;
            var len = parseInt(response.header("Content-Length"));
            var body = new Buffer(len);

            response.setEncoding('binary');

            response.on('data', function (chunk) {
                body.write(chunk, idx, "binary");
                idx += chunk.length;
            });

            response.on('end', function () {
                res.contentType = 'image/jpg';
                res.send(body);
            });

        }
    });

    reqGet.on('error', function (e) {
        // Send default image if error
        var file = 'img/user.png';
        fs.stat(file, function (err, stat) {
            var img = fs.readFileSync(file);
            res.contentType = 'image/png';
            res.contentLength = stat.size;
            res.end(img, 'binary');
        });
    });

    reqGet.end();

    return next();
}

Bạn không bao giờ nên sử dụng readFileSync bên trong các trình xử lý sự kiện. Đây là một hoạt động đồng bộ, chặn toàn bộ quá trình của bạn trong khi nó đọc tệp. Tôi đã giải thích nó trong câu trả lời của tôi chi tiết hơn.
rsp

5

Điều này có thể hơi lạc đề, vì bạn đang hỏi về việc phục vụ tệp tĩnh thông qua Node.js (trong đó fs.createReadStream('./image/demo.jpg').pipe(res) thực sự là một ý tưởng tốt), nhưng trong sản xuất, bạn có thể muốn có các tác vụ xử lý ứng dụng Node của mình, điều đó không thể được xử lý và phục vụ tĩnh không tải cho ví dụ Nginx.

Điều này có nghĩa là ít mã hóa hơn trong ứng dụng của bạn và hiệu quả tốt hơn vì các proxy ngược là do thiết kế lý tưởng cho việc này.


3

Hãy để tôi thêm vào các câu trả lời ở trên, rằng tối ưu hóa hình ảnh và phục vụ hình ảnh phản hồi giúp thời gian tải trang đáng kể, vì> 90% lưu lượng truy cập web là hình ảnh. Bạn có thể muốn xử lý trước hình ảnh bằng cách sử dụng các mô-đun JS / Node, chẳng hạn như fantemin và các trình cắm liên quan, lý tưởng trong quá trình xây dựng với Grunt hoặc Gulp .

Tối ưu hóa hình ảnh có nghĩa là xử lý tìm loại hình ảnh lý tưởng và chọn nén tối ưu để đạt được sự cân bằng giữa chất lượng hình ảnh và kích thước tệp.

Việc phân phát hình ảnh phản hồi sẽ tự động tạo ra một số kích thước và định dạng của từng hình ảnh và sử dụng srcsettrong html của bạn cho phép bạn cung cấp bộ hình ảnh tối ưu (nghĩa là định dạng và kích thước lý tưởng, do đó kích thước tệp tối ưu) cho mỗi trình duyệt).

Tự động hóa xử lý hình ảnh trong quá trình xây dựng có nghĩa là kết hợp nó một lần và trình bày hình ảnh được tối ưu hóa hơn nữa, đòi hỏi thêm thời gian tối thiểu.

Một số lớn đọc trên hình ảnh đáp ứng , việc rút gọn nói chung, imagemin mô-đun nút và sử dụng srcset .


1

Phương pháp này hiệu quả với tôi, nó không năng động nhưng đi thẳng vào vấn đề:

const fs      = require('fs');
const express = require('express');
const app     = express();

app.get( '/logo.gif', function( req, res ) {

  fs.readFile( 'logo.gif', function( err, data ) {

    if ( err ) {

      console.log( err );
      return;
    }

    res.write( data );
    return res.end();
  });

});

app.listen( 80 );

0

//This method involves directly integrating HTML Code in the res.write
//first time posting to stack ...pls be kind

const express = require('express');
const app = express();
const https = require('https');

app.get("/",function(res,res){
    res.write("<img src="+image url / src +">");
    res.send();
});

app.listen(3000, function(req, res) {
  console.log("the server is onnnn");
});

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.