呈现基本的HTML视图?


279

我有一个基本的node.js应用程序,我正在尝试使用Express框架。我有一个views存放index.html文件的文件夹。但是加载网络浏览器时收到以下错误。

错误:找不到模块“ html”

下面是我的代码。

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')

我在这里想念什么?

Answers:


298

您可以让玉器包含一个普通的HTML页面:

在views / index.jade中

include plain.html

在views / plain.html中

<!DOCTYPE html>
...

而且app.js仍然可以渲染玉:

res.render(index)

1
只是要注意,我想要的是仅提供一个.html文件,因为我的应用程序是单页;)
diosney

1
我们可以用这种方法包括多个HTML / JS页面吗?
user3398326

6
您不应该只为Express的初始测试而无需玉器模板就可以呈现该html页面吗?
PositiveGuy

1
那么,我们是否必须为每个HTML文件创建一个Jade模板?
克里斯

4
更多的是hack,而不是解决方案。
厄齐尔

226

这些答案中有许多已经过时。

使用express 3.0.0和3.1.0,可以进行以下工作:

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

有关Express 3.4+的替代语法和注意事项,请参见以下评论:

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

然后,您可以执行以下操作:

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

这假定您在views子文件夹中拥有视图,并且已经安装了ejs节点模块。如果没有,请在节点控制台上运行以下命令:

npm install ejs --save

@MichaelDausmann,加油,我已经在回答中包含了该信息。
Drew Noakes

为什么在这种情况下res.render需要.html扩展名,而在默认情况下,对于jade却不需要。使用样板代码,它只调用res.render('index',{title:'Express'}); 但这里是:res.render('about.html');
超越

6
使用Express 3.4.2:app.set('view engine','ejs');
罗兰

3
您应该使用命令“ npm install ejs --save”来更新您的package.json
Tom

8
为什么需要ejs?
PositiveGuy

71

从Express.js指南:视图渲染

查看文件名的格式为Express.ENGINE,其中ENGINE是所需模块的名称。例如,视图layout.ejs将告诉视图系统require('ejs'),加载的模块必须导出exports.render(str, options)符合Express 的方法,但是app.register()可以用来将引擎映射到文件扩展名,以便例如foo.html可以用jade渲染。

因此,您可以创建自己的简单渲染器,也可以只使用jade:

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

更多关于app.register

请注意,在Express 3中,此方法已重命名 app.engine


57
注意-app.register已在Express 3中重命名为app.engine。–
Spongeboy

8
请参阅Andrew Homeyer的回答。这是实际答案。
大卫·贝兹

7
从其他答案来看,对于Express 4,我最终使用了app.engine('.html', require('ejs').renderFile);
CrazyPyro,2015年

在express 4中,您还可以使用:app.set('view engine','jade');
Daniel Huang

48

您还可以阅读HTML文件并将其发送:

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

23
这种解决方案很糟糕,因为没有文件缓存;每个请求都会读取它。
Marcel Falliere'9

2
手动缓存它可能非常容易。只需将读取的文件存储一个变量,如果该变量为空,则仅再次读取。您还可以使用JS对象,并使用时间戳将各种文件存储在各种变量中。当然,它的工作量比大多数人要多,但是对于结识新手的人来说,这很好。这很容易理解
Naman Goel 2012年

5
kes 这使面向约定的精简体系结构(如MVC)的整个观点都失去了意义。
大卫·贝茨

@MarcelFalliere您假设他想缓存文件,或者他不想使用自定义缓存解决方案。谢谢keegan3d的回答。
本尼2015年

@MarcelFalliere然后,正确的解决方案是什么?我看到了其他需要新依赖项的答案。是否仅需要提供html文件?
JCarlosR

45

试试这个。这个对我有用。

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
在上面的确切配置上遇到了麻烦,因此我从“ .html”中删除了点并添加了以下内容:app.set('view engine','html'); app.set('views',__dirname +'/ views'); 一个完美的渲染
Bijou Trouvaille

8
这有点奇怪...您应该将html用作静态文件。这也给您带来更好的缓存的好处。创建自定义“ html编译器”似乎是错误的。如果您需要从路由内发送文件(很少需要这样做),则只需阅读并发送即可。否则,只需重定向到静态html。
enyo 2012年

2
@Enyo此评论似乎很奇怪,考虑到如何做您要说的是问的问题,而您的回答就是去做。您如何通过缓存提供静态HTML?
Kyeotic

3
我看到一个错误app.register。也许它已在Express 3.0.0.rc3中弃用了?TypeError: Object function app(req, res){ app.handle(req, res); } has no method 'register'
德鲁·诺阿克斯

1
@enyo,您错过了简化的体系结构的要点。当模式是控制器/视图(或/处理器/视图,无论您的特定体系结构是什么)时,使用过时的扩展模型都无法偏离该模式。您需要像对待其他内容一样将HTML视为呈现的内容。保持干燥,老兄。
大卫·贝兹

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

5
sendfile不在生产模式下缓存,因此这不是一个好的解决方案。
张宗平

1
@SeymourCakes如果我错了,请纠正我,但是我认为sendFile现在支持缓存:devdocs.io/express/index#res.sendFile
KhoPhi

19

如果您使用的是express@~3.0.0,请从示例中更改以下行:

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

像这样:

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

我按照Express api页面上的描述做了,它的工作原理就像魅力。通过该设置,您无需编写其他代码,因此可以轻松用于微型生产或测试。

完整代码如下:

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
app.use(express.static(__dirname + '/public'));启动服务器后为什么还要重复app.listen
fatuhoku 2013年

2
将html页面作为静态服务与仅通过express非静态地加载html页面有什么区别?
PositiveGuy

14

我在express 3.X和中也遇到了同样的问题node 0.6.16。以上给出的解决方案不适用于最新版本express 3.x。他们删除了app.register方法并添加了app.engine方法。如果尝试了上述解决方案,则可能会遇到以下错误。

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)

摆脱错误信息。将以下行添加到您的app.configure function

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

注意:您必须安装ejs模板引擎

npm install -g ejs

例:

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

注意:最简单的解决方案是将ejs模板用作视图引擎。在那里,您可以在* .ejs视图文件中编写原始HTML。


3
您必须在ejs全球安装吗?
德鲁·诺阿克斯

告诉我找不到'index.html'文件
MetaGuru 2012年

9

文件夹结构:

.
├── 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>

输出:

你好,世界


7

如果您不必使用views目录,只需将html文件公开下面目录中即可。

然后,将此行添加到app.configure而不是“ / views”中。

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

5

要在节点中呈现HTML页面,请尝试以下操作:

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

app.engine('html', require('ejs').renderFile);
  • 您需要通过以下方式安装ejs模块npm

       npm install ejs --save

这个解决方案对我有用。虽然我也尝试过静态选项。您能否解释其背后的机制。谢谢!
激进的

4

对于我的项目,我创建了以下结构:

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

此代码将index.html用于/请求,并将reset.css用于/css/reset.css请求。很简单,最好的部分是它会自动添加缓存标头

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)最好的方法是设置静态文件夹。在您的主文件中(app.js | server.js | ???):

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

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

然后,您从“ public”文件夹中获得了静态文件:

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

2)

您可以创建文件缓存。
使用方法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"] );                                
};);


3

使用Express 4.0.0,您唯一要做的就是在app.js中注释掉两行:

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

然后将您的静态文件放入/ public目录。示例:/public/index.html


3

我添加了下面的2行,它为我工作

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

它给我以下错误“错误:在Function.Module._resolveFilename(module.js:338:15)在Module.require(Function.Module._load(module.js:280:25)找不到模块'ejs' module.js:364:17)at require(module.js:380:17)“
Lygub Org 2015年

@LygubOrg npm install ejs --save在您的工作目录中运行。
A1rPun 2015年

1
是否有必要添加一个仅用于服务html文件的依赖项?
JCarlosR

3

尝试在Express路由中使用res.sendFile()函数。

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

在这里阅读:http : //codeforgeek.com/2015/01/render-html-file-expressjs/


3

我不想依靠ejs来简单地交付HTML文件,所以我只是自己写了一个小的渲染器:

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

我试图使用快速的RESTful API设置一个角度应用程序,并多次登陆该页面,尽管它没有帮助。这是我发现有效的内容:

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

然后在您的api路由的回调中如下所示: res.jsonp(users);

您的客户端框架可以处理路由。Express用于提供API。

我的回家路线如下所示:

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

这是快递服务器的完整文件演示!

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

希望对您有帮助!

// 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

将以下行添加到您的代码中

  1. 在package.json文件中,将“ jade”替换为“ *”并替换为“ ejs”和“ XYZ”(version)

      "dependencies": {
       "ejs": "*"
      }
  2. 然后在您的app.js文件中添加以下代码:

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

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

  3. 并记住将所有.HTML文件保留在views文件夹中

干杯:)


1

对于纯HTML,您不需要任何npm软件包或中间件

只需使用此:

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

1

令人遗憾的是,到2020年左右仍然没有添加一种不使用对象方法来呈现HTML页面的sendFile方法response。使用sendFile不是问题,但是以形式传递参数path.join(__dirname, 'relative/path/to/file')感觉不对。用户为什么要加入__dirname文件路径?默认情况下应完成。为什么不能通过取消项目目录来建立服务器的根目录?同样,仅安装模板依赖项以呈现静态HTML文件也是不正确的。我不知道解决该问题的正确方法,但是如果我必须提供静态HTML,那么我将执行以下操作:

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

上面的示例假定项目结构具有views目录,并且其中包含静态HTML文件。例如,假设views目录中有两个名为index.html和的HTML文件about.html,然后可以访问:localhost:8153/index.html或只是localhost:8153/加载index.html页面并localhost:8153/about.html加载来访问它们about.html。通过将工件存储在views目录中或仅使用默认dist/<project-name>目录并在服务器js中对其进行配置,我们可以使用类似的方法来服务React / Angular应用程序,如下所示:

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

0

我想允许对“ /”的请求由以前由静态中间件处理的Express路由处理。这将使我能够呈现常规版本的index.html或加载了级联+缩小的JS和CSS的版本,具体取决于应用程序设置。受到Andrew Homeyer的回答的启发,我决定将未经修改的HTML文件拖到views文件夹中,像这样配置Express

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

并像这样创建了一个路由处理程序

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

效果很好。


0

在server.js中,请包括

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

如果您要提供已包含所有内容的HTML文件,则不需要“呈现”它,而只需“提供”它。渲染是指在服务器将页面发送到浏览器之前更新服务器或注入内容时,它需要其他依赖项,例如ejs,如其他答案所示。

如果仅是基于浏览器的请求将其定向到文件,则应使用res.sendFile(),如下所示:

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

这样,除了快速表达之外,您不需要其他依赖项。如果您只想让服务器发送已经创建的html文件,则上述方法是一种非常轻巧的方法。


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

将您的index.html文件放在公用文件夹中

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

现在在终端中运行以下代码

节点index.js


-1

我通常用这个

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

请注意,因为这将共享/ web目录中的任何内容。

希望对您有所帮助


-2

如果您对node.js使用Express框架

安装npm ejs

然后添加配置文件

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)

;

从导出模块form.js渲染页面,在views目录中的html文件带有ejs文件名的扩展名为 form.html.ejs

然后创建form.js

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


这是什么烂摊子?
Vighnesh Raut
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.