渲染基本的 HTML 视图?
Posted
技术标签:
【中文标题】渲染基本的 HTML 视图?【英文标题】:Render basic HTML view? 【发布时间】:2011-05-30 14:21:36 【问题描述】:我有一个基本的 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')
我在这里错过了什么?
【问题讨论】:
【参考方案1】:来自 Express.js 指南:View Rendering
查看文件名采用
Express.ENGINE
的形式,其中ENGINE
是所需模块的名称。 例如视图layout.ejs
会告诉视图系统require('ejs')
,正在加载的模块必须导出方法exports.render(str, options)
以符合Express,但是@987654329 @ 可用于将引擎映射到文件扩展名,例如foo.html
可以被玉器渲染。
所以你要么创建自己的简单渲染器,要么只使用jade:
app.register('.html', require('jade'));
More 关于app.register
。
注意,在 Express 3 中,这个方法被重命名为
app.engine
【讨论】:
注意- app.register 在 Express 3 中已重命名为 app.engine。 查看 Andrew Homeyer 的回答。这是实际的答案。 从其他答案来看,对于 Express 4,我最终使用了app.engine('.html', require('ejs').renderFile);
在 express 4 中,你也可以使用:app.set('view engine', 'jade');【参考方案2】:
您也可以阅读 HTML 文件并将其发送:
app.get('/', (req, res) =>
fs.readFile(__dirname + '/public/index.html', 'utf8', (err, text) =>
res.send(text);
);
);
【讨论】:
这个解决方案很糟糕,因为没有缓存文件;每个请求都会读取它。 手动缓存它可能很容易。只需将读取的文件存储为变量,如果该变量为空,则仅再次读取。您还可以使用 JS 对象并将各种文件存储在各种变量中,并带有时间戳。当然,它比大多数人所做的工作要多,但是对于刚接触节点的人来说,这很好。很容易理解 哎呀。这违背了面向约定的流线型架构(如 MVC)的全部意义。 @MarcelFalliere 您假设他想要缓存文件,或者他不想使用自定义缓存解决方案。谢谢 keegan3d 的回答。 @MarcelFalliere 那么,什么是正确的解决方案?我看到其他需要新依赖项的答案。是否只需要提供 html 文件?【参考方案3】:试试这个。它对我有用。
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");
);
【讨论】:
上面的确切配置有问题,所以我从“.html”中删除了点并添加了这个:app.set('view engine', 'html'); app.set('views', __dirname + '/views');完美渲染 这有点奇怪...您应该将 html 作为静态文件提供。这也为您提供了更好的缓存的好处。创建自定义“html 编译器”似乎是错误的。如果您需要从路由中发送文件(您很少需要这样做),只需阅读并发送它。否则只需重定向到静态 html。 @Enyo 这个评论似乎很奇怪,考虑到如何做你所说的应该做的是被问到的问题,而你的答案就是去做。如何使用缓存提供静态 html? 我在app.register
上看到一个错误。也许它在 express 3.0.0.rc3 中已被弃用? TypeError: Object function app(req, res) app.handle(req, res); has no method 'register'
@enyo,您错过了流线型架构的要点。当模式是控制器/视图(或/处理器/视图,无论您的具体架构是什么)时,您都不能使用过时的扩展模型偏离该模式。您需要将 HTML 视为呈现的内容,就像其他所有内容一样。保持干燥,伙计。【参考方案4】:
app.get('/', function (req, res)
res.sendfile(__dirname + '/public/index.html');
);
【讨论】:
sendfile 在生产模式下没有缓存,所以这不是一个好的解决方案。 @SeymourCakes 如果我错了请纠正我,但我认为 sendFile 现在支持缓存:devdocs.io/express/index#res.sendFile【参考方案5】:你可以让 Jade 包含一个纯 HTML 页面:
在views/index.jade中
include plain.html
在views/plain.html中
<!DOCTYPE html>
...
而 app.js 仍然可以只渲染玉:
res.render(index)
【讨论】:
请注意,我想要只提供一个 .html 文件,因为我的应用是单页的;) 我们可以用这种方法包含多个 HTML/JS 页面吗? 难道不应该只为 express 的初始测试而在没有翡翠模板的情况下呈现该 html 页面吗? 那么我们是否必须为每个 HTML 文件创建一个翡翠模板? 更多的是 hack 而不是解决方案。【参考方案6】:对于我的项目,我创建了这个结构:
index.js
css/
reset.css
html/
index.html
此代码为/
请求提供index.html,为/css/reset.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);
【讨论】:
server.configure
已弃用,所以直接使用server.use
【参考方案7】:
我在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。
【讨论】:
一定要全局安装ejs
吗?
它告诉我它找不到'index.html'文件【参考方案8】:
其中许多答案已过时。
使用 express 3.0.0 和 3.1.0,以下工作:
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
有关 express 3.4+ 的替代语法和注意事项,请参阅下面的 cmets:
app.set('view engine', 'ejs');
然后你可以这样做:
app.get('/about', function (req, res)
res.render('about.html');
);
这假设您在views
子文件夹中有您的视图,并且您已经安装了ejs
节点模块。如果没有,请在 Node 控制台上运行以下命令:
npm install ejs --save
【讨论】:
为什么 res.render 在这种情况下需要 .html 扩展名,但在默认情况下不需要使用 jam。使用样板代码,它只调用 res.render('index', title: 'Express' );但在这里,它是: res.render('about.html'); @Transcendence,我不确定。也许您应该提出一个新问题。 使用 Express 3.4.2:app.set('view engine', 'ejs'); 你应该使用命令'npm install ejs --save'来更新你的package.json 为什么需要ejs?【参考方案9】:如果您不必使用 views 目录,只需将 html 文件移动到下面的 public 目录即可。
然后,将此行添加到 app.configure 而不是“/views”。
server.use(express.static(__dirname + '/public'));【讨论】:
【参考方案10】:如果您使用的是 express@~3.0.0,请从您的示例中更改以下行:
app.use(express.staticProvider(__dirname + '/public'));
到这样的事情:
app.set("view options", layout: false);
app.use(express.static(__dirname + '/public'));
我按照express api page 中的描述制作了它,它就像魅力一样。通过该设置,您无需编写额外的代码,因此很容易用于您的微生产或测试。
完整代码如下:
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')
【讨论】:
用app.listen
启动服务器后为什么要重复app.use(express.static(__dirname + '/public'));
?
将 html 页面作为静态服务与仅使用 express 加载非静态页面有什么区别?【参考方案11】:
我经常用这个
app.configure(function()
app.use(express.static(__dirname + '/web'));
);
请小心,因为这会共享 /web 目录中的任何内容。
希望对你有帮助
【讨论】:
【参考方案12】:如果你使用的是 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 渲染页面
在视图目录中有 html 文件
将 ejs 文件名扩展为
form.html.ejs
然后创建form.js
res.render('form.html.ejs');
【讨论】:
这是什么烂摊子?【参考方案13】:1) 最好的方法是设置静态文件夹。在您的主文件中(app.js | server.js | ???):
app.use(express.static(path.join(__dirname, 'public')));
public/css/form.html public/css/style.css
然后你从“公共”文件夹中获得静态文件:
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"] );
;);
【讨论】:
不错!这是一个完整的文件演示! https://gist.github.com/xgqfrms-GitHub/7697d5975bdffe8d474ac19ef906e906【参考方案14】:我试图用一个快速的 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)
);
【讨论】:
【参考方案15】:使用 Express 4.0.0,您唯一需要做的就是在 app.js 中注释掉 2 行:
/* app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade'); */ //or whatever the templating engine is.
然后将您的静态文件放到 /public 目录中。示例:/public/index.html
【讨论】:
【参考方案16】:我希望允许对“/”的请求由 Express 路由处理,而之前它们由静态中间件处理。这将允许我渲染 index.html 的常规版本或加载连接 + 缩小 JS 和 CSS 的版本,具体取决于应用程序设置。受Andrew Homeyer's answer 的启发,我决定将我的 HTML 文件(未经修改)拖到视图文件夹中,像这样配置 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');
);
效果很好。
【讨论】:
【参考方案17】:我在 2 行下面添加了它,它对我有用
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);
【讨论】:
它给了我以下错误“错误:在 Function.Module._resolveFilename (module.js:338:15) at Function.Module._load (module.js:280 :25) 在 Module.require (module.js:364:17) 在 require (module.js:380:17) " @LygubOrg 在您的工作目录中运行npm install ejs --save
。
是否只需要添加一个依赖来服务一个html文件?【参考方案18】:
在 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/
【讨论】:
【参考方案19】:res.sendFile(__dirname + '/public/login.html');
【讨论】:
【参考方案20】:在 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.
);
【讨论】:
【参考方案21】:将以下行添加到您的代码中
将 package.json 文件中的“jade”替换为“ejs”,将“X.Y.Z”(版本)替换为“*”
"dependencies":
"ejs": "*"
然后在您的 app.js 文件中添加以下代码:
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
记住将所有 .HTML 文件保存在视图文件夹中
干杯:)
【讨论】:
【参考方案22】:我不想依赖 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 );
);
【讨论】:
【参考方案23】:要在节点中呈现 Html 页面,请尝试以下操作,
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
你需要通过npm
安装ejs
模块,比如:
npm install ejs --save
【讨论】:
这个解决方案对我有用。虽然我也尝试过静态选项。你能解释一下它背后的机制吗?谢谢!【参考方案24】:这是快递服务器的完整文件演示!
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!
`);
);
【讨论】:
【参考方案25】:文件夹结构:
.
├── 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>
输出:
你好世界
【讨论】:
【参考方案26】:如果您尝试提供一个 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));
这样除了 express 之外你不需要额外的依赖。如果您只想让服务器发送您已经创建的 html 文件,那么上面是一种非常轻量级的方式。
【讨论】:
【参考方案27】:对于纯 html,您不需要任何 npm 包或中间件
就用这个吧:
app.get('/', function(req, res)
res.sendFile('index.html');
);
【讨论】:
【参考方案28】: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>
现在在终端中运行以下代码
节点索引.js
【讨论】:
【参考方案29】:很遗憾,到了 2020 年左右,express 还没有添加不使用 response
对象的 sendFile
方法来渲染 HTML 页面的方法。使用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
和about.html
的HTML 文件,那么要访问它们,我们可以访问:localhost:8153/index.html
或只是localhost:8153/
以加载index.html
页面和@ 987654334@ 加载about.html
。我们可以使用类似的方法来为 react/angular 应用程序提供服务,方法是将工件存储在 views
目录中,或者仅使用默认的 dist/<project-name>
目录并在服务器 js 中进行如下配置:
app.use(express.static('dist/<project-name>'));
【讨论】:
【参考方案30】:Express 4.x
res.sendFile(path [, options] [, fn])发送.html文件,没有模板引擎...
//...
// Node modules
const path = require('path')
//...
// Set path to views directory
app.set('views', path.join(__dirname, 'views'))
/**
* App routes
*/
app.get('/', (req, res) =>
res.sendFile('index.html', root: app.get('views') )
)
//...
.
├── node_modules
│
├── views
│ ├──index.html
└── app.js
【讨论】:
我必须使用var app = express(); app.set('views', path.join(__dirname, '../views'));
。如果没有“../folderName”,它会在路由文件夹中查找。以上是关于渲染基本的 HTML 视图?的主要内容,如果未能解决你的问题,请参考以下文章