So liefern Sie ein Bild mit nodejs


147

Ich habe ein Logo, das sich in der Öffentlichkeit / images / logo.gif befindet. Hier ist mein NodeJS-Code.

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

Es funktioniert, aber wenn ich nach localhost: 8080 / logo.gif frage, bekomme ich das Logo offensichtlich nicht.

Welche Änderungen muss ich tun, um ein Bild zu dienen.

Antworten:


224

Update 2016

Beispiele mit Express und ohne Express, die tatsächlich funktionieren

Diese Frage ist über 5 Jahre alt, aber jede Antwort hat einige Probleme .

TL; DR

Scrollen Sie nach unten, um Beispiele für ein Bild anzuzeigen:

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

Alle Beispiele finden Sie auch auf GitHub: https://github.com/rsp/node-static-http-servers

Testergebnisse sind auf Travis verfügbar: https://travis-ci.org/rsp/node-static-http-servers

Einführung

Nach über 5 Jahren, seit diese Frage gestellt wurde, gibt es nur eine richtige Antwort von Generalhenry, aber obwohl diese Antwort keine Probleme mit dem Code hat, scheint sie einige Probleme mit dem Empfang zu haben . Es wurde kommentiert, dass es "nicht viel anderes erklärt, als sich auf jemand anderen zu verlassen, um die Arbeit zu erledigen", und die Tatsache, wie viele Leute diesen Kommentar abgegeben haben, zeigt deutlich, dass viele Dinge einer Klärung bedürfen.

Zuallererst ist eine gute Antwort auf "Wie man Bilder mit Node.js bereitstellt" nicht, einen statischen Dateiserver von Grund auf neu zu implementieren und es schlecht zu machen. Eine gute Antwort ist die Verwendung eines Moduls wie Express, das die Aufgabe korrekt erledigt .

Bei der Beantwortung von Kommentaren, die besagen, dass die Verwendung von Express "nicht viel anderes erklärt, als sich auf eine andere Person zu verlassen, um die Arbeit zu erledigen" , sollte beachtet werden, dass die Verwendung des httpModuls bereits auf eine andere Person angewiesen ist, um die Arbeit zu erledigen. Wenn sich jemand nicht auf jemanden verlassen möchte, um die Arbeit zu erledigen, sollten stattdessen mindestens rohe TCP-Sockets verwendet werden - was ich in einem meiner folgenden Beispiele tue.

Ein ernsteres Problem ist , dass alle Antworten hier , dass die Verwendung httpModul sind gebrochen . Sie führen Rennbedingungen , unsicheren Weg Auflösung , die führen Path Traversal Schwachstelle , blockierte I / O , die vollständig wird keine gleichzeitigen Anfragen zu bedienen scheitern bei alle und anderen subtilen Problemen - sie werden als Beispiele für völlig gebrochen , was die Frage bezieht , und Dennoch verwenden sie bereits die vom httpModul bereitgestellte Abstraktion anstelle von TCP-Sockets, sodass sie nicht einmal alles von Grund auf neu machen, wie sie behaupten.

Wenn die Frage lautete: "Wie wird ein statischer Dateiserver als Lernübung von Grund auf neu implementiert?", Sollten auf jeden Fall Antworten dazu veröffentlicht werden - aber selbst dann sollten wir erwarten, dass sie zumindest korrekt sind . Es ist auch nicht unangemessen anzunehmen, dass jemand, der ein Bild bereitstellen möchte, in Zukunft möglicherweise mehr Bilder bereitstellen möchte, sodass man argumentieren könnte, dass das Schreiben eines bestimmten benutzerdefinierten statischen Dateiservers, der nur eine einzelne Datei mit fest codiertem Pfad bereitstellen kann, dies ist etwas kurzsichtig. Es ist schwer vorstellbar, dass jeder, der nach einer Antwort auf die Frage sucht, wie ein Bild bereitgestellt werden soll, sich mit einer Lösung zufrieden gibt, die nur ein einzelnes Bild anstelle einer allgemeinen Lösung für die Bereitstellung eines Bildes bereitstellt.

Kurz gesagt, die Frage ist, wie ein Image bereitgestellt werden kann, und eine Antwort darauf besteht darin, ein geeignetes Modul zu verwenden, um dies auf sichere, vorformende und zuverlässige Weise zu tun, das lesbar, wartbar und zukunftssicher ist und dabei die Best Practice des professionellen Knotens verwendet Entwicklung. Ich stimme jedoch zu, dass eine großartige Ergänzung zu einer solchen Antwort darin besteht, die gleiche Funktionalität manuell zu implementieren, aber leider ist jeder Versuch, dies zu tun, bisher gescheitert. Und deshalb habe ich einige neue Beispiele geschrieben.

Nach dieser kurzen Einführung sind hier meine fünf Beispiele, die die Arbeit auf 5 verschiedenen Abstraktionsebenen erledigen.

Minimale Funktionalität

Jedes Beispiel publicliefert Dateien aus dem Verzeichnis und unterstützt die Mindestfunktionalität von:

  • MIME-Typen für die meisten gängigen Dateien
  • dient HTML, JS, CSS, Klartext und Bildern
  • dient index.htmlals Standardverzeichnisindex
  • antwortet mit Fehlercodes für fehlende Dateien
  • Keine Schwachstellen bei der Pfadüberquerung
  • Keine Rennbedingungen beim Lesen von Dateien

Ich habe jede Version auf den Knotenversionen 4, 5, 6 und 7 getestet.

express.static

Diese Version verwendet die express.staticintegrierte Middleware des expressModuls.

Dieses Beispiel bietet die meisten Funktionen und die geringste Menge an Code.

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

Diese Version verwendet das expressModul, jedoch ohne express.staticMiddleware. Das Bereitstellen statischer Dateien wird als einzelner Routenhandler mithilfe von Streams implementiert.

Dieses Beispiel enthält einfache Gegenmaßnahmen zur Pfadüberquerung und unterstützt eine begrenzte Anzahl der gängigsten MIME-Typen.

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

Diese Version verwendet das connectModul, das eine Abstraktionsebene niedriger als ist express.

Dieses Beispiel hat eine ähnliche Funktionalität wie die expressVersion, verwendet jedoch APIs mit etwas niedrigerem Hebel.

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

Diese Version verwendet das httpModul, das die niedrigste API für HTTP in Node ist.

Dieses Beispiel hat ähnliche Funktionen wie die connectVersion, verwendet jedoch noch mehr APIs auf niedrigerer Ebene.

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

Diese Version verwendet das netModul, das die niedrigste API für TCP-Sockets in Node ist.

Dieses Beispiel enthält einige Funktionen der httpVersion, aber das minimale und unvollständige HTTP-Protokoll wurde von Grund auf neu implementiert. Da es keine Chunked-Codierung unterstützt, werden die Dateien in den Speicher geladen, bevor sie bereitgestellt werden, um die Größe zu ermitteln, bevor eine Antwort gesendet wird, da das Einsetzen der Dateien und das anschließende Laden eine Race-Bedingung einführen würde.

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/');
});

Beispiele herunterladen

Ich habe alle Beispiele mit mehr Erklärungen auf GitHub gepostet.

Beispiele mit express.static, express, connect, httpund net:

Andere Projekte, die nur Folgendes verwenden express.static:

Tests

Testergebnisse sind auf Travis verfügbar:

Alles wird auf den Knotenversionen 4, 5, 6 und 7 getestet.

Siehe auch

Andere verwandte Antworten:


8
Beste und vollständige Antwort auf die Frage. Schade, ich kann dich nur einmal positiv bewerten.
Kulvar

3
Es sollte einen Weg geben, Vintage-Fragen wie diese zu überarbeiten! Ich habe gerade eine Stunde damit verschwendet, die 110-Stimmen-Antwort zum Laufen zu bringen. Schließlich habe ich nach unten gescrollt, nur um zu überprüfen. Ihre Antwort könnte (sollte) ein Lehrbuch zum Thema sein.
Thailandian

2
Beste Antwort und im Detail. Sollte die markierte die akzeptierte Antwort sein. Danke Kumpel !!!
Prabodh M

Ich weiß nicht, warum jemand Express verwenden würde. Ich habe es am Anfang wahrscheinlich auch getan, weil es alle anderen getan haben. Dann wurde mir klar, dass die Verwendung des http-Moduls von Node der richtige Ansatz ist. Dafür ist es vorgesehen. Sie erhalten viel Flexibilität. Sie verstehen das HTTP-Protokoll und können problemlos debuggen. Express bietet viel Jargon und eine dünne Schicht über dem http-Modul, die mit der Rohcodierung mit dem http-Modul einfach zu implementieren ist. Ich empfehle jedem Benutzer von Express oder einem anderen solchen Modul dringend, sich von ihnen zu entfernen und das http-Modul direkt zu verwenden.
Sunny

1
Ein Hinweis, den ich für Neulinge wie mich erwähnen möchte: Wenn wir einen Ordner als statisch deklarieren, können express.staticwir das Bild durch Aufrufen der URL abrufen http://ip:port/path_after_the_static_folder. Wir müssen den statischen Ordner selbst nicht erwähnen, um das Bild bereitzustellen. Wir können dies jedoch hinzufügen, indem wir es der Einfachheitapp.use('/static', express.static(imagePath))
halber

159

Ich stimme den anderen Postern zu, dass Sie irgendwann ein Framework wie Express verwenden sollten. Aber zuerst sollten Sie auch verstehen, wie man so etwas Grundlegendes ohne Bibliothek macht, um wirklich zu verstehen, was die Bibliothek für Sie abstrahiert Schritte sind

  1. Analysieren Sie die eingehende HTTP-Anforderung, um festzustellen, nach welchem ​​Pfad der Benutzer fragt
  2. Fügen Sie in der bedingten Anweisung einen Pfad hinzu, auf den der Server antworten soll
  3. Wenn das Image angefordert wird, lesen Sie die Image-Datei von der Festplatte.
  4. Stellen Sie den Bildinhaltstyp in einer Kopfzeile bereit
  5. Servieren Sie den Bildinhalt im Körper

Der Code würde ungefähr so ​​aussehen (nicht getestet)

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
Sie sollten readFileSync nicht mitten in einer Antwort verwenden. Beim ersten Tic sollte entweder eine Synchronisierungslast verwendet werden, oder es sollte die asynchrone Methode verwendet werden. codr.cc/s/5d0b73d6/js
Generalhenry

1
Bei der Synchronisierungsversion bin ich mit Ihnen an Bord. Bei der asynchronen Version bestand die Gefahr der Verwendung nicht blockierender Vorgänge für Dateien darin, dass die Antwort gesendet werden konnte, bevor die gesamte Datei gelesen wurde, und Sie am Ende verlassen konnte mit einer Teildatei, die dem Benutzer zugestellt wird? Müssen Sie eine Blockcodierung verwenden, wenn Sie eine gelesene asynchrone Datei verwenden?
Noli

1
fs.readFileSync ruft erst zurück, wenn die gesamte Datei geladen ist, sodass keine Chunk-Behandlung erforderlich ist. Die Chunk-Verarbeitung dient hauptsächlich der Übertragung von Netzwerkdateien (da die Dinge länger dauern können als erwartet).
Generalhenry

9
Die Linie res.end(img);sollte sein res.end(img, 'binary');. Gute Arbeit!
Honza Pokorny

3
+1 für "aber zuerst sollten Sie auch verstehen, wie man so etwas Grundlegendes ohne Bibliothek macht, um wirklich zu verstehen, was die Bibliothek für Sie abstrahiert."
Sunny

67

Sie sollten das Express- Framework verwenden.

npm install express

und dann

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

und dann sollte die URL localhost: 8080 / images / logo.gif funktionieren.


18
Sicher, erklärt aber nicht viel anderes, als sich auf jemand anderen zu verlassen, um die Arbeit zu erledigen.
LeeGee

Ich habe eine Vanilleknoten-Version (nur Kernmodule) hinzugefügt.
Generalhenry

+ I Dies ist die einzige richtige Antwort, die bisher veröffentlicht wurde. Ich erkläre es in meiner Antwort ausführlicher.
rsp

15

Es ist zu spät, hilft aber jemandem, den ich benutze node version v7.9.0undexpress version 4.15.0

Wenn Ihre Verzeichnisstruktur ungefähr so ​​ist:

your-project
   uploads
   package.json
   server.js

server.js code:

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

Vanilla Node Version wie gewünscht:

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
Sie möchten nicht nach fs.exists(Rennbedingungen) suchen, es wäre eine bessere Angewohnheit, einen Fehler beim Verrohren zu bemerken.
Brendan

Obwohl die Überprüfung in diesem Fall nicht der Knotenweg ist, ist alles andere an dieser Antwort 1 Million Mal besser als die akzeptierte Antwort.
Ninjaxor

1
Ich stimme @BrendanAshworth zu. Die Rennbedingungen sind in fast allen Antworten hier vorhanden. Ich habe in meiner Antwort mehr darüber geschrieben . Aber ein großes Lob für das Schreiben mit Streams. Fast alle anderen Antworten verwenden readFileSync, das blockiert und in keinem Event-Handler verwendet werden sollte.
rsp

1
var filePath = path.resolve ('public', '.' + parts.pathname); response.writeHead (200, {'Content-Type': mime.lookup (parts.pathname)}); mime - Paket mime-Typ von 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');

einfach und auf den Punkt, viel besser als die ausdrücklichen Antworten. Dies verdient 1000 Gegenstimmen. Nur ein Tipp: Vielleicht entfernen Sie das Code-Snippet und ersetzen es durch nur Javascript-Text
bluejayke

Wäre es möglich, einen Parameter zu übergeben, damit './image/:jpg jedes Bild bedienen kann?
Prav

13

Ich verwende gerne Restify für REST-Services. In meinem Fall hatte ich einen REST-Service zum Bereitstellen von Bildern erstellt. Wenn eine Bildquelle 404/403 zurückgab, wollte ich ein alternatives Bild zurückgeben. Folgendes habe ich mir ausgedacht, um einige der Dinge hier zu kombinieren:

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();
}

Sie sollten readFileSync niemals in Ereignishandlern verwenden. Dies ist eine synchrone Operation, die Ihren gesamten Prozess blockiert, während die Datei gelesen wird. Ich habe es in meiner Antwort ausführlicher erklärt.
rsp

5

Dies mag ein wenig vom Thema abweichen, da Sie speziell nach statischen Dateien fragen, die über Node.js bereitgestellt werden (wo dies fs.createReadStream('./image/demo.jpg').pipe(res)eigentlich eine gute Idee ist), aber in der Produktion möchten Sie möglicherweise, dass Ihre Node-App Aufgaben erledigt, die sonst nicht angegangen werden können und statische Entladung, die zB Nginx dient.

Dies bedeutet weniger Codierung in Ihrer App und eine bessere Effizienz, da Reverse-Proxys von Natur aus ideal dafür sind.


3

Lassen Sie mich nur zu den obigen Antworten hinzufügen, dass die Optimierung von Bildern und das Bereitstellen von reaktionsschnellen Bildern die Ladezeiten von Seiten erheblich verkürzt, da> 90% des Webverkehrs Bilder sind. Möglicherweise möchten Sie Images mithilfe von JS / Node-Modulen wie Imagemin und verwandten Plug-Ins vorverarbeiten , idealerweise während des Erstellungsprozesses mit Grunt oder Gulp .

Um Bilder zu optimieren , müssen Sie einen idealen Bildtyp finden und die optimale Komprimierung auswählen, um ein Gleichgewicht zwischen Bildqualität und Dateigröße zu erreichen.

Das Bereitstellen von reaktionsschnellen Bildern führt dazu, dass für jedes Bild automatisch mehrere Größen und Formate erstellt werden. Durch die Verwendung srcsetin Ihrem HTML-Code können Sie für jeden einzelnen Browser einen optimalen Bildsatz (dh das ideale Format und die idealen Abmessungen, also die optimale Dateigröße) bereitstellen.

Die Automatisierung der Bildverarbeitung während des Erstellungsprozesses bedeutet, sie einmal zu integrieren und anschließend optimierte Bilder zu präsentieren, was nur minimale zusätzliche Zeit erfordert.

Einige großartige Informationen zu reaktionsschnellen Bildern , zur Minimierung im Allgemeinen, zum Imagemin- Knotenmodul und zur Verwendung von srcset .


1

Diese Methode funktioniert bei mir, sie ist nicht dynamisch, sondern direkt auf den Punkt gebracht:

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 );
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.