呈现原始HTML

26

我想使用Express 3来呈现原始的.html页面,方法如下:

server.get('/', function(req, res) {
    res.render('login.html');
}

这是我配置服务器以呈现原始HTML页面的方法(灵感来自于这个过时的问题):

server
    .set('view options', {layout: false})
    .set('views', './../')
    .engine('html', function(str, options) {
        return function(locals) {
             return str;
        };
    });

不幸的是,使用这个配置会导致页面挂起,无法正确渲染。我做错了什么?如何在Express 3中呈现原始HTML而不使用Jade和EJS等高级渲染引擎?


决定通过Nodejs提供静态HTML的动机是什么?孤立地看,它似乎不是最优解。 - Richard Marr
3
这是一个非常简单的页面。例如,使用Jade来进行开发的开销并不值得。 - Randomblue
好的,假设在现有高流量Node应用程序中存在一个受到重击的静态页面,没有共享模板的要求。即使如此,对我来说这似乎仍然是太多的编码工作,编码意味着开发成本+测试+维护。我个人会在响应上设置长时间缓存头,并让Nginx / Apache从缓存中提供内容。这样,您就不需要自定义代码,而且模板生成开销变得无关紧要。 - Richard Marr
4
实际上,这些是使用JavaScript在客户端填充的静态HTML页面。生成填充信息的实时数据由Node.JS生成。我不会放弃使用Node.JS。 - Randomblue
我确实使用Node作为Web服务器,没有涉及Nginx。虽然我有WebSocket,但这可能对我的目的来说有些过于前沿了。 - Randomblue
显示剩余2条评论
11个回答

46

我认为你想表达的是:如何提供静态html文件,对吗?

让我们开始吧。

首先,这是我的一个项目中的一些代码:

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

这意味着我的应用文件夹中有一个名为public的文件夹。所有的静态内容,如css、js甚至html页面都在这里。

要发送静态的html页面,只需在您的应用程序文件中添加此内容。

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/layout.html');
});

因此,如果你拥有一个名为 xyz.com 的域名,每当有人访问该域名时,他们的浏览器就会提供 layout.html。

编辑

如果你正在使用 express 4,情况有些不同。路由和中间件将按照它们放置的顺序执行。

一个好的技巧是在所有标准路由之后立即放置静态文件服务代码。像这样:

// All standard routes are above here
app.post('/posts', handler.POST.getPosts);

// Serve static files
app.use(express.static('./public'));

这非常重要,因为它有可能消除您代码中的瓶颈。看看这个stackoverflow答案(其中他谈到了优化的第一个答案)。

Express 4.0 的另一个主要变化是您不需要使用app.configure()


2
非常好用 - 在我的情况下,我使用了相对路径,最终出现了403错误,所以使用了:res.sendfile(path.resolve('../path/to/index.html')); - Michael
抱歉提出这么旧的帖子 - 但是 sendfile 是否会缓存内容?还是在发送之前实际读取文件? - Martol1ni
@Martol1ni 我不是很确定。在我的测试中,我更改了单个HTML文件的内容,express能够提供更新后的副本,因此我认为它默认情况下不会缓存。但是,我认为你正在寻找这个:https://github.com/isaacs/st - shash7
1
请使用sendFile代替已经被弃用的sendfile。 - Gonzalo.-

20

如果您实际上不需要将数据注入模板中,Express 中最简单的解决方案是使用静态文件服务器 (express.static())。

然而,如果您仍想手动连接路由到页面(例如,您的示例将“ /”映射到“ login.html”),您可以尝试使用res.sendFile()来发送您的 HTML 文档:

http://expressjs.com/api.html#res.sendfile


1
res.sendFile()确实会发送HTML文件,但不会发送所有相关的CSS、JS等文件。它似乎不适合手动路由。 - Randomblue
为了发送CSS、JS等文件,最简单的机制是使用express.static()来提供服务...实际上是出于相反的原因,因为sendFile()需要手动路由,而static()将自动服务静态页面。 - hunterloftis
@Randomblue 请看我的回答,处理CSS和JavaScript,否则你会遇到一堆404错误。 - FredTheWebGuy
2
记录一下,它是小写字母F的sendfile。奇怪的是它不是驼峰式命名,但就是这样。 - WuTheFWasThat

19

你尝试过使用fs模块吗?

server.get('/', function(req, res) {
    fs.readFile('index.html', function(err, page) {
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(page);
        res.end();
    });
}

显然,这不是生产就绪的,因为它没有缓存结果。 - Randomblue
1
Randomblue,这对你来说不应该是个问题,因为你正在提供静态文件,所以(a)在生产中,静态内容的缓存应该由您的Web服务器而不是应用程序服务器处理,(b)您正在提供静态文件而不是处理模板,因此性能损失远低于正常情况。 - Richard Marr

7
根据文档所述,app.engine(...)函数的格式应为:'Express expects: (path, options, callback)'。因此,您可以像下面这样编写代码(为简便起见,但它可以工作):
server
.set('view options', {layout: false})
.set('views', './../')
.engine('html', function(path, options, cb) {
    fs.readFile(path, 'utf-8', cb);
});

当然,就像2#和3#所说的那样,您应该使用express.static()进行静态文件传输;上面的代码不适用于生产。

6

首先,你所犯的错误是尝试在express 3.0中使用express 2.x代码片段来呈现原始HTML。从express 3.0开始,视图引擎将仅传递文件路径而不是文件内容。

解决方案如下:

创建一个简单的视图引擎

var fs = require('fs'); 

function rawHtmlViewEngine(filename, options, callback) {
    fs.readFile(filename, 'utf8', function(err, str){
        if(err) return callback(err);

        /*
         * if required, you could write your own 
         * custom view file processing logic here
         */

        callback(null, str);
    }); 
}

使用方法如下

server.engine('html', rawHtmlViewEngine)
server.set('views', './folder');
server.set('view engine', 'html');


参考

官方 express 2.x 到 3.x 迁移指南

请参考此链接中的 '模板引擎集成' 部分 https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x


2

在安装最新版本的Express后

express the_app_name

创建一个包含 app.js 的基本目录。

app.js 文件中有一行代码:

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

一个名为public的文件夹是魔法发生的地方...

路由是通过以下方式建模的函数完成的:

app.get('/', function(req,res) {
      res.sendfile('public/name_of_static_file.extension');
    });

*例子:* 当通过以下行调用时,public文件夹中的 index.html 将被提供:

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

在资产方面: 确保从与public文件夹相关的文件夹中调用css和javascript文件。

一个普通的Express安装将有stylesheetsjavascriptsimages作为起始文件夹。因此,请确保脚本和css表格在index.html中具有正确的路径:

示例:

<link href="stylesheets/bootstrap.css" rel="stylesheet">

或者

<script src="javascripts/jquery.js"></script>

0

多年后,这里有一个新的答案。

实际上,这种方法与skypecakes的回答类似;

var fs = require('fs');

app.get('/', function(req, res, next) {
    var html = fs.readFileSync('./html/login.html', 'utf8')
    res.send(html)
})

就这些...

如果使用 EJS 或 Jade,可以使用下面的代码:

var fs = require('fs');

app.get('/', function(req, res, next) {
    var html = fs.readFileSync('./html/login.html', 'utf8')
    res.render('login', { html: html })
})

views/login.ejs 文件仅包含以下代码:

<%- locals.html %>

0
我想这样做是因为我正在创建一个模板 NodeJS 服务器,我不想将其绑定到视图引擎。为此,拥有一个占位符渲染引擎非常有用,它只需返回(html)文件内容即可。
以下是我想出的方法:
//htmlrenderer.js

'use strict';

var fs = require('fs'); // for reading files from the file system

exports.renderHtml = function (filePath, options, callback) { // define the template engine
    fs.readFile(filePath, function (err, content) {
        if (err) return callback(new Error(err));
        var rendered = content.toString();
        // Do any processing here...
        return callback(null, rendered);
    });
};

使用它:

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

来源:http://expressjs.com/zh-cn/advanced/developing-template-engines.html

欢迎留下评论和建设性反馈!


0

您可以使用res.sendFile()发送文件。 您可以将所有HTML文件保存在views文件夹中,并可以在options变量中设置路径。

app.get('/', (req, res)=>{
    var options = {  root: __dirname + '/../views/' };
      var fileName = 'index.html';
      res.sendFile(fileName, options);
});

0
app.get('/', function(req, res) {
  returnHtml(res, 'index');
});

function returnHtml(res, name) {
  res.sendFile(__dirname + '/' + name + '.html');
}

将您的index.html放到根目录下,当然您也可以创建一个/views文件夹并扩展returnHtml()函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接