Grundlegende HTML-Ansicht rendern?


279

Ich habe eine grundlegende node.js-App, die ich mithilfe des Express-Frameworks auf den Weg bringen möchte. Ich habe einen viewsOrdner, in dem ich eine index.htmlDatei habe. Beim Laden des Webbrowsers wird jedoch die folgende Fehlermeldung angezeigt.

Fehler: Modul 'html' kann nicht gefunden werden

Unten ist mein Code.

var express = require('express');
var app = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')

Was fehlt mir hier?

Antworten:


298

Sie können Jade eine einfache HTML-Seite hinzufügen lassen:

in views / index.jade

include plain.html

in views / plain.html

<!DOCTYPE html>
...

und app.js kann immer noch nur Jade rendern:

res.render(index)

1
Nur um zu beachten, dass ich nur eine HTML-Datei
bereitstellen

1
Können wir dieser Methode mehrere HTML / JS-Seiten hinzufügen?
user3398326

6
sollten Sie nicht in der Lage sein, diese HTML-Seite ohne Jade-Vorlage nur für den ersten Test von Express zu rendern?
PositiveGuy

1
Müssen wir also für jede unserer HTML-Dateien eine Jade-Vorlage erstellen?
Chris - Jr

4
Eher ein Hack als eine Lösung.
Ozil

226

Viele dieser Antworten sind veraltet.

Mit Express 3.0.0 und 3.1.0 funktioniert Folgendes:

app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);

In den Kommentaren unten finden Sie alternative Syntax und Einschränkungen für Express 3.4+:

app.set('view engine', 'ejs');

Dann können Sie so etwas tun wie:

app.get('/about', function (req, res)
{
    res.render('about.html');
});

Dies setzt voraus, dass Sie Ihre Ansichten im viewsUnterordner haben und das ejsKnotenmodul installiert haben . Wenn nicht, führen Sie Folgendes auf einer Knotenkonsole aus:

npm install ejs --save

@ MichaelDausmann, Prost, ich habe diese Informationen in die Antwort aufgenommen.
Drew Noakes

Warum benötigt die res.render in diesem Fall die Erweiterung .html, nicht jedoch im Standardfall mit Jade? Mit dem Boilerplate-Code wird nur res.render ('index', {title: 'Express'}) aufgerufen. aber hier ist es: res.render ('about.html');
Transzendenz

6
Mit Express 3.4.2: app.set ('view engine', 'ejs');
Roland

3
Sie sollten den Befehl 'npm install ejs --save' verwenden, um Ihr package.json
Tom Teman

8
warum brauchst du ejs
PositiveGuy

71

Aus dem Express.js-Handbuch: Rendering anzeigen

Dateinamen anzeigen haben die Form Express.ENGINE, in der ENGINEder Name des Moduls angegeben ist, das benötigt wird. Beispielsweise layout.ejsteilt die Ansicht dem Ansichtssystem mitrequire('ejs') , dass das zu ladende Modul die Methode exportieren mussexports.render(str, options) , um Express zu entsprechen. Sie app.register()kann jedoch verwendet werden, um Engines Dateierweiterungen zuzuordnen, damit sie beispielsweise foo.htmlvon Jade gerendert werden können.

Entweder erstellen Sie Ihren eigenen einfachen Renderer oder Sie verwenden einfach Jade:

 app.register('.html', require('jade'));

Mehr über app.register.

Beachten Sie, dass diese Methode in Express 3 umbenannt wird app.engine


57
Hinweis- app.register wurde in Express 3 in app.engine umbenannt.
Spongeboy

8
Siehe Antwort von Andrew Homeyer. Es ist die eigentliche Antwort.
David Betz

7
Aus einer anderen Antwort geht hervor, dass ich für Express 4app.engine('.html', require('ejs').renderFile);
CrazyPyro

In Express 4 können Sie auch Folgendes verwenden: app.set ('view engine', 'jade');
Daniel Huang

48

Sie können die HTML-Datei auch lesen und senden:

app.get('/', (req, res) => {
    fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) => {
        res.send(text);
    });
});

23
Diese Lösung ist schlecht, da die Dateien nicht zwischengespeichert werden. es wird für jede Anfrage gelesen.
Marcel Falliere

2
Es ist möglicherweise ziemlich einfach, es manuell zwischenzuspeichern. Speichern Sie die gelesene Datei einfach als Variable und lesen Sie sie nur dann erneut, wenn diese Variable leer ist. Sie können auch ein JS-Objekt verwenden und verschiedene Dateien in verschiedenen Variablen mit Zeitstempeln speichern. Sicher, es ist mehr Arbeit als die meisten Leute, aber es ist gut mit Leuten, die neu im Knoten sind. Es ist leicht zu verstehen
Naman Goel

5
Huch. Dies macht den gesamten Punkt konventionell orientierter, optimierter Architekturen (wie MVC) zunichte.
David Betz

@MarcelFalliere Sie gehen davon aus, dass er die Datei zwischenspeichern oder keine benutzerdefinierte Caching-Lösung verwenden möchte. Danke keegan3d für die Antwort.
Benny

@MarcelFalliere Was ist dann die richtige Lösung? Ich sehe andere Antworten, die neue Abhängigkeiten erfordern. Ist es nur zum Servieren von HTML-Dateien erforderlich?
JCarlosR

45

Versuche dies. Für mich geht das.

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

  // make a custom html template
  app.register('.html', {
    compile: function(str, options){
      return function(locals){
        return str;
      };
    }
  });
});

....

app.get('/', function(req, res){
  res.render("index.html");
});

2
hatte Probleme mit der genauen Konfiguration oben, also entfernte ich den Punkt aus ".html" und fügte Folgendes hinzu: app.set ('view engine', 'html'); app.set ('views', __dirname + '/ views'); für einen perfekten Render
Bijou Trouvaille

8
Das ist ein bisschen komisch ... Sie sollten HTML als statische Dateien bereitstellen. Dies gibt Ihnen auch den Vorteil eines besseren Caching. Das Erstellen eines benutzerdefinierten "HTML-Compilers" scheint falsch. Wenn Sie eine Datei innerhalb einer Route senden müssen (was Sie sehr selten tun müssen), lesen Sie sie einfach und senden Sie sie. Andernfalls leiten Sie einfach zum statischen HTML um.
Enyo

2
@Enyo dieser Kommentar scheint seltsam, wenn man bedenkt, wie man das macht, was man sagt, ist die Frage, die gestellt wird, und seine Antwort ist, es einfach zu tun. Wie dient man einem statischen HTML mit Caching?
Kyeotic

3
Ich sehe einen Fehler am app.register. Vielleicht ist es in Express 3.0.0.rc3 veraltet? TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
Drew Noakes

1
@enyo, du hast den Punkt der Steamlined-Architektur verpasst. Wenn das Muster Controller / Ansicht (oder / Prozessor / Ansicht, unabhängig von Ihrer spezifischen Architektur) ist, können Sie mit dem veralteten Modell der Erweiterungen nicht davon abweichen. Sie müssen Ihren HTML-Code wie alles andere als gerenderten Inhalt behandeln. Halte es trocken, Alter.
David Betz

22
app.get('/', function (req, res) {
res.sendfile(__dirname + '/public/index.html');
});

5
sendfile ist im Produktionsmodus kein Cache, daher ist dies keine gute Lösung.
Teo Choong Ping

1
@SeymourCakes Bitte korrigieren Sie mich, wenn ich falsch liege, aber ich denke, sendFile unterstützt jetzt das Caching: devdocs.io/express/index#res.sendFile
KhoPhi

19

Wenn Sie express@~3.0.0 verwenden, ändern Sie die folgende Zeile aus Ihrem Beispiel:

app.use(express.staticProvider(__dirname + '/public'));

zu so etwas:

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

Ich habe es wie auf der Express-API-Seite beschrieben gemacht und es funktioniert wie Charme. Mit diesem Setup müssen Sie keinen zusätzlichen Code schreiben, damit er für Ihre Mikroproduktion oder Tests problemlos verwendet werden kann.

Vollständiger Code unten aufgeführt:

var express = require('express');
var app = express.createServer();

app.set("view options", {layout: false});
app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8080, '127.0.0.1')

1
Warum wiederholen Sie, app.use(express.static(__dirname + '/public'));nachdem Sie den Server mit gestartet haben app.listen?
Fatuhoku

2
Was ist der Unterschied zwischen dem Bereitstellen der HTML-Seite als statisch und dem Laden der nicht statischen Seite mit Express?
PositiveGuy

14

Ich hatte auch das gleiche Problem in express 3.Xund node 0.6.16. Die oben angegebene Lösung funktioniert nicht für die neueste Version express 3.x. Sie haben die app.registerMethode entfernt und die Methode hinzugefügt app.engine. Wenn Sie die oben genannte Lösung ausprobiert haben, wird möglicherweise der folgende Fehler angezeigt.

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
    at Function.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:37:5)
    at Function.configure (/home/user1/ArunKumar/firstExpress/node_modules/express/lib/application.js:399:61)
    at Object.<anonymous> (/home/user1/ArunKumar/firstExpress/app.js:22:5)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:31)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:40)

Um die Fehlermeldung loszuwerden. Fügen Sie die folgende Zeile zu Ihrem hinzuapp.configure function

app.engine('html', require('ejs').renderFile);

Hinweis: Sie müssen die ejsTemplate-Engine installieren

npm install -g ejs

Beispiel:

app.configure(function(){

  .....

  // disable layout
  app.set("view options", {layout: false});

  app.engine('html', require('ejs').renderFile);

....

app.get('/', function(req, res){
  res.render("index.html");
});

Hinweis: Die einfachste Lösung besteht darin, die ejs-Vorlage als Ansichtsmodul zu verwenden. Dort können Sie Roh-HTML in * .ejs-Ansichtsdateien schreiben.


3
Müssen Sie ejsglobal installieren ?
Drew Noakes

Es sagt mir, dass es die 'index.html'-Datei nicht finden kann
MetaGuru

9

Ordnerstruktur:

.
├── index.html
├── node_modules
   ├──{...}
└── server.js

server.js

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

app.use(express.static('./'));

app.get('/', function(req, res) {
    res.render('index.html');
});

app.listen(8882, '127.0.0.1')

index.html

<!DOCTYPE html>
<html>
<body>

<div> hello world </div>

</body>
</html>

Ausgabe:

Hallo Welt


7

Wenn Sie das Verzeichnis views nicht verwenden müssen , verschieben Sie einfach HTML-Dateien in das unten stehende öffentliche Verzeichnis.

Fügen Sie diese Zeile dann in app.configure anstelle von '/ views' ein.

server.use (express.static (__ dirname + '/ public'));

5

Um die HTML-Seite im Knoten zu rendern, versuchen Sie Folgendes:

app.set('views', __dirname + '/views');

app.engine('html', require('ejs').renderFile);
  • Sie müssen das ejsModul npmwie folgt installieren :

       npm install ejs --save

Diese Lösung hat bei mir funktioniert. Obwohl ich auch statische Option versucht habe. Können Sie den Mechanismus dahinter erklären? Vielen Dank!
Hardad

4

Für mein Projekt habe ich folgende Struktur erstellt:

index.js
css/
    reset.css
html/
    index.html

Dieser Code dient index.html für /Anforderungen und reset.css für /css/reset.cssAnforderungen. Einfach genug, und das Beste daran ist, dass automatisch Cache-Header hinzugefügt werden .

var express = require('express'),
    server = express();

server.configure(function () {
    server.use('/css', express.static(__dirname + '/css'));
    server.use(express.static(__dirname + '/html'));
});

server.listen(1337);

3

1) Der beste Weg ist, einen statischen Ordner festzulegen. In Ihrer Hauptdatei (app.js | server.js | ???):

app.use(express.static(path.join(__dirname, 'public')));

public / css / form.html
public / css / style.css

Dann haben Sie eine statische Datei aus dem "öffentlichen" Ordner:

http://YOUR_DOMAIN/form.html
http://YOUR_DOMAIN/css/style.css

2)

Sie können Ihren Dateicache erstellen.
Verwenden Sie die Methode fs.readFileSync

var cache = {};
cache["index.html"] = fs.readFileSync( __dirname + '/public/form.html');

app.get('/', function(req, res){    
    res.setHeader('Content-Type', 'text/html');
    res.send( cache["index.html"] );                                
};);

nicht schlecht! Hier ist eine vollständige Datei-Demo! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906
xgqfrms

3

Mit Express 4.0.0 müssen Sie nur 2 Zeilen in app.js auskommentieren:

/* app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); */ //or whatever the templating engine is.

Und legen Sie dann Ihre statische Datei im Verzeichnis / public ab. Beispiel: /public/index.html


3

Ich habe unter 2 Zeilen hinzugefügt und es funktioniert für mich

    app.set('view engine', 'html');
    app.engine('html', require('ejs').renderFile);

es gibt mir den folgenden Fehler "Fehler: Modul 'ejs' kann bei Function.Module._resolveFilename (module.js: 338: 15) bei Function.Module._load (module.js: 280: 25) bei Module.require (nicht gefunden werden) module.js: 364: 17) at require (module.js: 380: 17) "
Lygub Org

@LygubOrg npm install ejs --savein Ihrem Arbeitsverzeichnis ausführen .
A1rPun

1
Ist es notwendig, eine Abhängigkeit nur hinzuzufügen, um eine HTML-Datei zu bedienen?
JCarlosR

3

Versuchen Sie die Funktion res.sendFile () in Express-Routen.

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


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});

app.get('/about',function(req,res){
  res.sendFile(path.join(__dirname+'/about.html'));
});

app.get('/sitemap',function(req,res){
  res.sendFile(path.join(__dirname+'/sitemap.html'));
});

app.listen(3000);

console.log("Running at Port 3000");

Lesen Sie hier: http://codeforgeek.com/2015/01/render-html-file-expressjs/


3

Ich wollte mich nicht auf ejs verlassen, um einfach eine HTML-Datei zu liefern, also habe ich einfach den winzigen Renderer selbst geschrieben:

const Promise = require( "bluebird" );
const fs      = Promise.promisifyAll( require( "fs" ) );

app.set( "view engine", "html" );
app.engine( ".html", ( filename, request, done ) => {
    fs.readFileAsync( filename, "utf-8" )
        .then( html => done( null, html ) )
        .catch( done );
} );

2

Ich habe versucht, eine eckige App mit einer Express-RESTful-API einzurichten, und bin mehrmals auf dieser Seite gelandet, obwohl dies nicht hilfreich war. Folgendes hat funktioniert:

app.configure(function() {
    app.use(express.static(__dirname + '/public'));         // set the static files location
    app.use(express.logger('dev'));                         // log every request to the console
    app.use(express.bodyParser());                          // pull information from html in POST
    app.use(express.methodOverride());                      // simulate DELETE and PUT
    app.use(express.favicon(__dirname + '/public/img/favicon.ico'));
});

Dann sehen Sie im Rückruf für Ihre API-Routen wie folgt aus: res.jsonp(users);

Ihr clientseitiges Framework kann das Routing übernehmen. Express dient zur Bereitstellung der API.

Meine Heimatroute sieht folgendermaßen aus:

app.get('/*', function(req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});


2

Hier ist eine vollständige Datei-Demo von Express Server!

https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906

hoffe es wird dir helfen!

// simple express server for HTML pages!
// ES6 style

const express = require('express');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const app = express();

let cache = [];// Array is OK!
cache[0] = fs.readFileSync( __dirname + '/index.html');
cache[1] = fs.readFileSync( __dirname + '/views/testview.html');

app.get('/', (req, res) => {
    res.setHeader('Content-Type', 'text/html');
    res.send( cache[0] );
});

app.get('/test', (req, res) => {
    res.setHeader('Content-Type', 'text/html');
    res.send( cache[1] );
});

app.listen(port, () => {
    console.log(`
        Server is running at http://${hostname}:${port}/ 
        Server hostname ${hostname} is listening on port ${port}!
    `);
});


1

Fügen Sie Ihrem Code die folgenden Zeilen hinzu

  1. Ersetzen Sie "jade" durch "ejs" & "XYZ" (Version) durch "*" in der Datei package.json

      "dependencies": {
       "ejs": "*"
      }
  2. Fügen Sie dann in Ihrer app.js-Datei folgenden Code hinzu:

    app.engine('html', require('ejs').renderFile);

    app.set('view engine', 'html');

  3. Und denken Sie daran, alle HTML-Dateien im Ansichtsordner zu behalten

Prost :)


1

Für einfaches HTML benötigen Sie kein npm-Paket oder keine Middleware

benutze einfach das:

app.get('/', function(req, res) {
    res.sendFile('index.html');
});

1

Es ist sehr traurig, dass es um 2020 geht. Express hat noch keine Möglichkeit hinzugefügt, eine HTML-Seite ohne die sendFileMethode des responseObjekts zu rendern . Die Verwendung sendFileist kein Problem, aber die Weitergabe von Argumenten in Form von path.join(__dirname, 'relative/path/to/file')fühlt sich nicht richtig an. Warum sollte sich ein Benutzer __dirnamedem Dateipfad anschließen? Dies sollte standardmäßig erfolgen. Warum kann das Stammverzeichnis des Servers nicht standardmäßig im Projektverzeichnis sein? Außerdem ist die Installation einer Vorlagenabhängigkeit zum Rendern einer statischen HTML-Datei erneut nicht korrekt. Ich weiß nicht, wie ich das Problem richtig angehen soll, aber wenn ich einen statischen HTML-Code bereitstellen müsste, würde ich Folgendes tun:

const PORT = 8154;

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

app.use(express.static('views'));

app.listen(PORT, () => {
    console.log(`Server is listening at port http://localhost:${PORT}`);
});

Im obigen Beispiel wird davon ausgegangen, dass die Projektstruktur ein viewsVerzeichnis enthält und sich die statischen HTML-Dateien darin befinden. Nehmen wir zum Beispiel an, das viewsVerzeichnis hat zwei HTML-Dateien mit dem Namen, index.htmlund about.htmlum darauf zuzugreifen, können wir Folgendes besuchen: localhost:8153/index.htmloder einfach localhost:8153/, um die index.htmlSeite localhost:8153/about.htmlzu laden und die zu laden about.html. Wir können einen ähnlichen Ansatz verwenden, um eine React / Angular-App bereitzustellen, indem wir die Artefakte im viewsVerzeichnis speichern oder einfach das Standardverzeichnis verwenden dist/<project-name>und es auf dem Server js wie folgt konfigurieren:

app.use(express.static('dist/<project-name>'));

0

Ich wollte zulassen, dass Anfragen an "/" über eine Express-Route verarbeitet werden, wo sie zuvor von der statischen Middleware verarbeitet wurden. Dies würde es mir ermöglichen, die reguläre Version von index.html oder eine Version zu rendern, die verkettetes + minimiertes JS und CSS geladen hat, abhängig von den Anwendungseinstellungen. Inspiriert von Andrew Homeyers Antwort habe ich beschlossen, meine HTML-Dateien - unverändert - in einen Ansichtsordner zu ziehen und Express so zu konfigurieren

   app.engine('html', swig.renderFile);
   app.set('view engine', 'html');
   app.set('views', __dirname + '/views');  

Und so einen Routen-Handler erstellt

 app.route('/')
        .get(function(req, res){
            if(config.useConcatendatedFiles){
                return res.render('index-dist');
            }
            res.render('index');       
        });

Das hat ganz gut geklappt.


0

In server.js bitte einfügen

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


app.get('/',function(req,res){
  res.sendFile(path.join(__dirname+'/index.html'));
  //__dirname : It will resolve to your project folder.
});

0

Wenn Sie versuchen, eine HTML-Datei bereitzustellen, in der BEREITS der gesamte Inhalt enthalten ist, muss sie nicht "gerendert", sondern nur "bereitgestellt" werden. Beim Rendern wird der Server aktualisiert oder Inhalte eingefügt, bevor die Seite an den Browser gesendet wird, und es sind zusätzliche Abhängigkeiten wie ejs erforderlich, wie die anderen Antworten zeigen.

Wenn Sie den Browser einfach auf der Grundlage ihrer Anforderung auf eine Datei leiten möchten, sollten Sie res.sendFile () wie folgt verwenden :

const express = require('express');
const app = express();
var port = process.env.PORT || 3000; //Whichever port you want to run on
app.use(express.static('./folder_with_html')); //This ensures local references to cs and js files work

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/folder_with_html/index.html');
});

app.listen(port, () => console.log("lifted app; listening on port " + port));

Auf diese Weise benötigen Sie neben Express keine zusätzlichen Abhängigkeiten. Wenn Sie nur möchten, dass der Server Ihre bereits erstellten HTML-Dateien sendet, ist dies eine sehr einfache Möglichkeit.


0

index.js

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


app.get('/', function(req, res) {
    res.render('index.html');
});


app.listen(3400, () => {
    console.log('Server is running at port 3400');
})

Legen Sie Ihre index.html-Datei in einem öffentlichen Ordner ab

<!DOCTYPE html>
<html>
<head>
    <title>Render index html file</title>
</head>
<body>
    <h1> I am from public/index.html </h1>
</body>
</html>

Führen Sie nun den folgenden Code in Ihrem Terminal aus

Knoten index.js


-1

Ich benutze das normalerweise

app.configure(function() {
    app.use(express.static(__dirname + '/web'));
});

Seien Sie vorsichtig, da dadurch alles im Verzeichnis / web freigegeben wird.

Ich hoffe, es hilft


-2

Wenn Sie das Express-Framework für node.js verwenden

installiere npm ejs

Fügen Sie dann die Konfigurationsdatei hinzu

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router)

;;

Rendern der Seite aus dem Exportmodul form.js hat die HTML-Datei im Ansichtsverzeichnis mit der Erweiterung des Dateinamens ejs als form.html.ejs

Erstellen Sie dann die Datei form.js.

res.render('form.html.ejs');


Was ist das für ein Durcheinander?
Vighnesh Raut
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.