Jak wyświetlać obraz za pomocą nodejs


147

Mam logo, które znajduje się w public / images / logo.gif. Oto mój kod nodejs.

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

Działa, ale kiedy pytam o localhost: 8080 / logo.gif, to oczywiście nie dostaję logo.

Jakie zmiany muszę wprowadzić, aby wyświetlać obraz.

Odpowiedzi:


224

Aktualizacja 2016

Przykłady z Express i bez Express, które faktycznie działają

To pytanie ma ponad 5 lat, ale każda odpowiedź ma jakieś problemy .

TL; DR

Przewiń w dół, aby zobaczyć przykłady, z którymi można wyświetlać obraz z:

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

Wszystkie przykłady są również na GitHub: https://github.com/rsp/node-static-http-servers

Wyniki testów są dostępne na Travis: https://travis-ci.org/rsp/node-static-http-servers

Wprowadzenie

Po ponad 5 latach od zadania tego pytania jest tylko jedna prawidłowa odpowiedź od generalhenry, ale chociaż ta odpowiedź nie ma problemów z kodem, wydaje się, że ma pewne problemy z odbiorem . Stwierdzono, że to „niewiele wyjaśnia poza tym, jak polegać na kimś innym, aby wykonał swoją pracę”, a fakt, jak wiele osób głosowało na ten komentarz, wyraźnie pokazuje, że wiele rzeczy wymaga wyjaśnienia.

Po pierwsze, dobrą odpowiedzią na pytanie „Jak obsługiwać obrazy przy użyciu Node.js” nie jest implementowanie statycznego serwera plików od zera i robienie tego źle. Dobrą odpowiedzią jest użycie modułu takiego jak Express, który wykonuje zadanie poprawnie .

Odpowiadając na komentarze, które mówią, że używanie Express "nie wyjaśnia wiele poza tym, jak polegać na kimś innym, aby wykonał zadanie" , należy zauważyć, że korzystanie z httpmodułu już zależy od kogoś innego do wykonania zadania. Jeśli ktoś nie chce polegać na nikim, aby wykonał zadanie, zamiast tego należy użyć przynajmniej surowych gniazd TCP - co robię w jednym z poniższych przykładów.

Poważniejszym problemem jest to, że wszystkie odpowiedzi, które używają httpmodułu, są zepsute . Wprowadzają warunki wyścigu , niezabezpieczone rozwiązywanie ścieżek , które doprowadzą do podatności na przemierzanie ścieżki , blokowanie we / wy , które w ogóle nie będą obsługiwać żadnych równoczesnych żądań i inne subtelne problemy - są całkowicie zepsute jako przykłady tego, o co chodzi w pytaniu, oraz jednak używają już abstrakcji dostarczanej przez httpmoduł zamiast używać gniazd TCP, więc nie robią nawet wszystkiego od zera, jak twierdzą.

Jeśli pytanie brzmiało: „Jak zaimplementować statyczny serwer plików od podstaw, jako ćwiczenie szkoleniowe”, to z całą pewnością należy opublikować odpowiedzi, jak to zrobić - ale nawet wtedy powinniśmy oczekiwać, że przynajmniej będą poprawne . Nie jest też nierozsądne założenie, że ktoś, kto chce wyświetlać obraz, może chcieć udostępniać więcej obrazów w przyszłości, więc można argumentować, że napisanie określonego niestandardowego serwera plików statycznych, który może obsługiwać tylko jeden plik ze ścieżką zakodowaną na stałe, jest nieco krótkowzroczny. Trudno sobie wyobrazić, że każdy, kto szuka odpowiedzi na temat sposobu wyświetlania obrazu, byłby zadowolony z rozwiązania, które obsługuje tylko jeden obraz, zamiast ogólnego rozwiązania obsługującego dowolny obraz.

Krótko mówiąc, pytanie brzmi, jak obsłużyć obraz, a odpowiedzią na to jest użycie odpowiedniego modułu, aby zrobić to w bezpieczny, skuteczny i niezawodny sposób, który jest czytelny, łatwy w utrzymaniu i przyszłościowy przy wykorzystaniu najlepszych praktyk profesjonalnych Node rozwój. Ale zgadzam się, że świetnym dodatkiem do takiej odpowiedzi byłoby pokazanie sposobu ręcznego zaimplementowania tej samej funkcjonalności, ale niestety każda próba wykonania tego zawiodła. Dlatego napisałem kilka nowych przykładów.

Po tym krótkim wprowadzeniu, oto pięć moich przykładów wykonywania pracy na 5 różnych poziomach abstrakcji.

Minimalna funkcjonalność

Każdy przykład obsługuje pliki z publickatalogu i obsługuje minimalną funkcjonalność:

  • Typy MIME dla większości popularnych plików
  • obsługuje HTML, JS, CSS, zwykły tekst i obrazy
  • służy index.htmljako domyślny indeks katalogu
  • odpowiada kodami błędów dla brakujących plików
  • brak luk w przechodzeniu przez ścieżkę
  • brak warunków wyścigu podczas odczytu plików

Testowałem każdą wersję na Node w wersjach 4, 5, 6 i 7.

express.static

Ta wersja korzysta z express.staticwbudowanego oprogramowania pośredniego expressmodułu.

Ten przykład ma największą funkcjonalność i najmniejszą ilość kodu.

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

Ta wersja używa expressmodułu, ale bez express.staticoprogramowania pośredniego. Obsługa plików statycznych jest implementowana jako procedura obsługi pojedynczej trasy przy użyciu strumieni.

Ten przykład zawiera proste środki zaradcze przy przechodzeniu po ścieżce i obsługuje ograniczony zestaw najpopularniejszych typów MIME.

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

Ta wersja używa connectmodułu, który jest o jeden poziom abstrakcji niższy niż express.

Ten przykład ma podobną funkcjonalność do expresswersji, ale używa nieco mniejszych dźwigni API.

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

Ta wersja używa httpmodułu, który jest interfejsem API najniższego poziomu dla HTTP w Node.

Ten przykład ma podobną funkcjonalność do connectwersji, ale wykorzystuje jeszcze więcej interfejsów API niższego poziomu.

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

Ta wersja używa netmodułu, który jest interfejsem API najniższego poziomu dla gniazd TCP w Node.

Ten przykład zawiera niektóre funkcje httpwersji, ale minimalny i niekompletny protokół HTTP został zaimplementowany od podstaw. Ponieważ nie obsługuje kodowania fragmentarycznego, ładuje pliki do pamięci przed udostępnieniem im informacji o rozmiarze przed wysłaniem odpowiedzi, ponieważ statystyka plików, a następnie ładowanie wprowadziłoby stan wyścigu.

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

Pobierz przykłady

Opublikowałem wszystkie przykłady na GitHub z dokładniejszym wyjaśnieniem.

Przykłady z express.static, express, connect, httpi net:

Inny projekt wykorzystujący tylko express.static:

Testy

Wyniki testów są dostępne w Travisie:

Wszystko jest testowane na Node w wersjach 4, 5, 6 i 7.

Zobacz też

Inne powiązane odpowiedzi:


8
Najlepsza i kompletna odpowiedź na pytanie. Szkoda, mogę cię zagłosować tylko raz.
— Kulvar,

3
Powinien istnieć sposób na odświeżenie starych pytań, takich jak ten! Po prostu zmarnowałem godzinę, próbując uzyskać odpowiedź na 110 głosów. W końcu przewinąłem w dół, żeby sprawdzić. Twoja odpowiedź mogłaby (powinna) być podręcznikiem na ten temat.
— Tajlandia

2
Najlepsza odpowiedź i wszystkie szczegóły. Powinna być zaznaczona zaakceptowana odpowiedź. Dzięki stary !!!
— Prabodh M

Nie wiem, dlaczego ktoś miałby używać Expressu. Ja też zrobiłem na początku, prawdopodobnie dlatego, że wszyscy inni. Wtedy zdałem sobie sprawę, że użycie modułu http Node jest właściwym podejściem. Właśnie to jest przewidziane. Masz dużą elastyczność. Znasz protokół HTTP i możesz łatwo debugować. Express zapewnia dużo żargonu i cienką warstwę na module http, który jest łatwy do zaimplementowania przy użyciu surowego kodowania za pomocą modułu http. Zdecydowanie zalecam każdemu użytkownikowi Express lub jakiegokolwiek innego takiego modułu odejście od nich i bezpośrednie użycie modułu http.
— Słoneczny

1
uwaga, o której chciałbym wspomnieć dla początkujących użytkowników, takich jak ja: kiedy deklarujemy folder jako statyczny za pomocą express.static, możemy pobrać obraz, wywołując adres URL http://ip:port/path_after_the_static_folder, nie musimy wspominać o samym folderze statycznym, aby wyświetlić obraz. Chociaż możemy to dodać, używając app.use('/static', express.static(imagePath))dla wygody jako standardowej dokumentacji w: expressjs.com/en/starter/static-files.html
— Rakibul Haq,

160

Zgadzam się z innymi plakatami, że w końcu powinieneś użyć frameworka, takiego jak Express .. ale najpierw powinieneś także zrozumieć, jak zrobić coś tak fundamentalnego bez biblioteki, aby naprawdę zrozumieć, co biblioteka dla ciebie streszcza. kroki są

  1. Przeanalizuj przychodzące żądanie HTTP, aby zobaczyć, o którą ścieżkę prosi użytkownik
  2. Dodaj ścieżkę w instrukcji warunkowej, na którą serwer ma odpowiedzieć
  3. Jeśli zażądano obrazu, przeczytaj plik obrazu z dysku.
  4. Wyświetlaj typ zawartości obrazu w nagłówku
  5. Podawaj zawartość obrazu w treści

Kod wyglądałby mniej więcej tak (nie testowano)

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
Nie powinieneś używać readFileSync w środku odpowiedzi. W pierwszym tiku należy użyć obciążenia synchronizacji lub należy użyć metody asynchronicznej. codr.cc/s/5d0b73d6/js
— generalhenry

1
Jestem z tobą na pokładzie w wersji do synchronizacji, jednak w przypadku wersji asynchronicznej pomyślałem, że niebezpieczeństwo używania operacji nieblokujących dla plików polega na tym, że może wysłać odpowiedź, zanim cały plik zostanie odczytany, i ostatecznie cię zostawi z częściowym plikiem udostępnianym użytkownikowi? Czy musisz używać kodowania fragmentarycznego, jeśli używasz odczytu pliku asynchronicznego?
— noli

1
fs.readFileSync nie wywołuje zwrotnego, dopóki cały plik nie zostanie załadowany, więc nie ma potrzeby obsługi porcji. Obsługa fragmentów służy głównie do przesyłania plików w sieci (ponieważ może to potrwać dłużej niż oczekiwano).
— generalhenry,

9
Linia res.end(img);powinna być res.end(img, 'binary');. Dobra robota!
— Honza Pokorny

3
+1 za „ale najpierw powinieneś także zrozumieć, jak zrobić coś tak fundamentalnego bez biblioteki, aby naprawdę zrozumieć, co biblioteka przedstawia dla ciebie ..”
— Słoneczny

67

Powinieneś użyć Express Framework.

npm install express

i wtedy

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

a wtedy powinien działać adres URL localhost: 8080 / images / logo.gif .


18
Bezpieczne, ale niewiele wyjaśnia poza tym, jak polegać na kimś innym, aby wykonał zadanie.
— LeeGee

Dodałem wersję vanilla node (tylko podstawowe moduły).
— generalhenry

+ I To jest jedyna poprawna odpowiedź opublikowana do tej pory. Dokładniej wyjaśniam to w mojej odpowiedzi .
— rsp

15

Jest już za późno, ale komuś pomaga, używam node version v7.9.0iexpress version 4.15.0

jeśli struktura katalogów jest podobna do tej:

your-project
   uploads
   package.json
   server.js

Kod 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

Wersja węzła waniliowego na żądanie:

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
Nie chcesz sprawdzać fs.exists(stan wyścigu), lepszym nawykiem byłoby wykrycie błędu podczas orurowania.
— Brendan,

Chociaż w tym przypadku sprawdzanie nie jest metodą węzła, wszystko inne w tej odpowiedzi jest 1 milion razy lepsze niż zaakceptowana odpowiedź.
— Ninjaxor

1
Zgadzam się z @BrendanAshworth. Warunki wyścigu są obecne w prawie wszystkich odpowiedziach tutaj. Więcej o tym pisałem w mojej odpowiedzi . Ale brawo za pisanie tego za pomocą strumieni. Prawie wszystkie inne odpowiedzi używają readFileSync, który blokuje i nie powinien być używany w żadnych programach obsługi zdarzeń.
— rsp

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

proste i na temat, o wiele lepsze niż odpowiedzi ekspresowe… to zasługuje na 1000 głosów poparcia. Tylko wskazówka: może usuń fragment kodu i zastąp go tylko tekstem javascript
— bluejayke.

czy byłoby możliwe przekazanie parametru tak, aby „./image/:jpg” wyświetlało dowolne zdjęcie?
— Prav

13

Lubię używać Restify dla usług REST. W moim przypadku utworzyłem usługę REST do obsługi obrazów, a następnie, jeśli źródło obrazu zwróciło 404/403, chciałem zwrócić obraz alternatywny. Oto, co wymyśliłem, łącząc niektóre z tych rzeczy:

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

Nigdy nie należy używać readFileSync wewnątrz programów obsługi zdarzeń. Jest to operacja synchroniczna, która blokuje cały proces podczas odczytywania pliku. Wyjaśniłem to bardziej szczegółowo w mojej odpowiedzi .
— rsp

5

Może to być trochę nie na temat, ponieważ pytasz konkretnie o obsługę plików statycznych przez Node.js (gdzie fs.createReadStream('./image/demo.jpg').pipe(res)jest to dobry pomysł), ale w środowisku produkcyjnym możesz chcieć, aby aplikacja Node obsługiwała zadania, z którymi nie można sobie poradzić w inny sposób i statyczne odciążanie służące np. do Nginx.

Oznacza to mniej kodowania w aplikacji i lepszą wydajność, ponieważ odwrotne proxy są do tego idealne.


3

Pozwólcie, że dodam do powyższych odpowiedzi, że optymalizacja obrazów i wyświetlanie responsywnych obrazów radykalnie pomaga w ładowaniu stron, ponieważ> 90% ruchu internetowego to obrazy. Możesz chcieć wstępnie przetworzyć obrazy za pomocą modułów JS / Node, takich jak imagemin i powiązane wtyczki, najlepiej podczas procesu kompilacji za pomocą Grunt lub Gulp .

Optymalizacja obrazów oznacza przetwarzanie w celu znalezienia idealnego typu obrazu i wybrania optymalnej kompresji w celu uzyskania równowagi między jakością obrazu a rozmiarem pliku.

Podawanie responsywnych obrazów przekłada się na automatyczne tworzenie kilku rozmiarów i formatów każdego obrazu, a użycie srcsetw html pozwala na serwowanie optymalnego zestawu obrazów (czyli idealnego formatu i wymiarów, a tym samym optymalnego rozmiaru pliku) dla każdej przeglądarki).

Automatyzacja przetwarzania obrazu podczas procesu kompilacji oznacza jednorazowe włączenie go i dalsze prezentowanie zoptymalizowanych obrazów, co wymaga minimalnego dodatkowego czasu.

Jakiś wielki przeczytać na reagujących obrazów , minifikacji w ogóle, imagemin modułu węzła i za pomocą srcset .


1

Ta metoda działa dla mnie, nie jest dynamiczna, ale od razu do rzeczy:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.