node.js 错误:未指定默认引擎且未提供扩展

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23595282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 17:19:06  来源:igfitidea点击:

Error: No default engine was specified and no extension was provided

node.jshttpexpress

提问by Kobojunkie

I am working through setting up a http server using node.js and engine. However, I keep running into issues that I have little information on how to resolve I would appreciate some help solving this please.

我正在使用 node.js 和引擎设置 http 服务器。但是,我一直遇到问题,我对如何解决的信息知之甚少,我将不胜感激,请帮助解决此问题。

Error: No default engine was specified and no extension was provided. 
at new View (...\node_modules\express\lib\view.js:41:42) 
at Function.app.render (...\node_modules\express\lib\application.js:484:12) 
at ServerResponse.res.render (...\node_modules\express\lib\response.js:783:7) 
at Layer.handle (...\app.js:123:7) 
at trim_prefix (...\node_modules\express\lib\router\index.js:225:17) 
at c (...\node_modules\express\lib\router\index.js:198:9) 
at Function.proto.process_params (...\node_modules\express\lib\router\index.js:253:12) 
at next (...\node_modules\express\lib\router\index.js:189:19) 
at next (...\node_modules\express\lib\router\index.js:202:7) 
at next (...\node_modules\express\lib\router\index.js:166:38)

Below is what I have set up to start up this engine.

下面是我为启动这个引擎所做的设置。

var http = require('http');  
var module = require("module")
var logger = require('morgan');
var express = require('express');
var app =  module.exports = express();
var silent = 'test' == process.env.NODE_ENV;
var httpServer = http.createServer(app);  // app middleware

app.enable('strict routing');
// app.all('*', function(req, res, next)/*** CORS support.*/
// {
//   if (!req.get('Origin')) return next();// use "*" here to accept any origin
//   res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
//   res.set('Access-Control-Allow-Methods', 'GET, POST');
//   res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
//   res.set('Access-Control-Allow-Max-Age', 3600);
//   if ('OPTIONS' == req.method) return res.send(200);
//   next();
// });
app.set('views', __dirname + '/views'); // general config
app.set('view engine', 'html');
app.get('/404', function(req, res, next){
next();// trigger a 404 since no other middleware will match /404 after this one, and we're not responding here
});
app.get('/403', function(req, res, next){// trigger a 403 error
  var err = new Error('not allowed!');
  err.status = 403;
  next(err);
});
app.get('/500', function(req, res, next){// trigger a generic (500) error
  next(new Error('keyboard cat!'));
});
app.use(express.static(__dirname + '/public')); 
//error handlers
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);  
// middleware with an arity of 4 are considered error handling middleware. When you next(err)
// it will be passed through the defined middleware in order, but ONLY those with an arity of 4, ignoring regular middleware.
function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {// whatever you want here, feel free to populate properties on `err` to treat it differently in here.
  res.send(err.status || 500, { error: err.message });
  } 
  else 
  { next(err);}
};
// create an error with .status. we can then use the property in our custom error handler (Connect repects this prop as well)
function error  (status, msg) {
  var err = new Error(msg);
  err.status = status;
  return err;
};
function logErrors  (err, req, res, next) {
  console.error(err.stack);
  next(err);
};
function errorHandler (err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
};

// Error handlers
// Since this is the last non-error-handling middleware use()d, we assume 404, as nothing else responded.
// $ curl http://localhost:3000/notfound
// $ curl http://localhost:3000/notfound -H "Accept: application/json"
// $ curl http://localhost:3000/notfound -H "Accept: text/plain"
app.use(function(req, res, next){
  res.status(404); 
  if (req.accepts('html')) {// respond with html page
    res.render('404', { url: req.url });
    return;
  } 
  if (req.accepts('json')) {// respond with json
    res.send({ error: 'Not found' });
    return;
  } 
  res.type('txt').send('Not found');// default to plain-text. send()
});

// error-handling middleware, take the same form as regular middleware, however they require an
// arity of 4, aka the signature (err, req, res, next).when connect has an error, it will invoke ONLY error-handling middleware.

// If we were to next() here any remaining non-error-handling middleware would then be executed, or if we next(err) to
// continue passing the error, only error-handling middleware would remain being executed, however here
// we simply respond with an error page.
app.use(function(err, req, res, next){
  // we may use properties of the error object here and next(err) appropriately, or if we possibly recovered from the error, simply next().
  res.status(err.status || 500);
  res.render('500', { error: err });
});

if (!module.parent) {// assigning to exports will not modify module, must use module.exports
  app.listen(3000);
  silent || console.log('Express started on port 3000');
};

回答by Pylinux

The res.render stuff will throw an error if you're not using a view engine.

如果您不使用视图引擎, res.render 内容将引发错误。

If you just want to serve json replace the res.render('error', { error: err });lines in your code with:

如果您只想提供 json res.render('error', { error: err });,请将代码中的行替换为:

res.json({ error: err })

PS: People usually also have message in the returned object:

PS:人们通常在返回的对象中也有消息:

res.status(err.status || 500);
res.json({
  message: err.message,
  error: err
});

回答by alessandro

You are missing the view engine, for example use jade:

您缺少视图引擎,例如使用jade

change your

改变你的

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

with

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

If you want use a html friendly syntax use instead ejs

如果您想使用 html 友好的语法,请使用ejs

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

EDIT

编辑

As you can read from view.js Express View Module

正如您可以从 view.js Express View Module 中读取的那样

module.exports = View;

/**
 * Initialize a new `View` with the given `name`.
 *
 * Options:
 *
 *   - `defaultEngine` the default template engine name
 *   - `engines` template engine require() cache
 *   - `root` root path for view lookup
 *
 * @param {String} name
 * @param {Object} options
 * @api private
 */

function View(name, options) {
  options = options || {};
  this.name = name;
  this.root = options.root;
  var engines = options.engines;
  this.defaultEngine = options.defaultEngine;
  var ext = this.ext = extname(name);
  if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
  if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
  this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
  this.path = this.lookup(name);
}

You must have installed a default engine

你一定已经安装了 default engine

Expresssearch default layout view by program.templateas you can read below:

Express搜索默认布局视图,program.template如下所示:

mkdir(path + '/views', function(){
      switch (program.template) {
        case 'ejs':
          write(path + '/views/index.ejs', ejsIndex);
          break;
        case 'jade':
          write(path + '/views/layout.jade', jadeLayout);
          write(path + '/views/index.jade', jadeIndex);
          break;
        case 'jshtml':
          write(path + '/views/layout.jshtml', jshtmlLayout);
          write(path + '/views/index.jshtml', jshtmlIndex);
          break;
        case 'hjs':
          write(path + '/views/index.hjs', hoganIndex);
          break;

      }
    });

and as you can read below:

正如您可以在下面阅读的那样:

program.template = 'jade';
if (program.ejs) program.template = 'ejs';
if (program.jshtml) program.template = 'jshtml';
if (program.hogan) program.template = 'hjs';

the default view engine is jade

默认视图引擎是 jade

回答by caokey

Comment out the res.renderlines in your code and add in next(err);instead. If you're not using a view engine, the res.renderstuff will throw an error.

注释掉res.render代码中的行并添加进来next(err);。如果你没有使用视图引擎,这些res.render东西会抛出一个错误。

Sorry, you'll have to comment out this line as well:

抱歉,您还必须注释掉这一行:

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

My solution would result in not using a view engine though. You don't need a view engine, but if that's the goal, try this:

我的解决方案会导致不使用视图引擎。您不需要视图引擎,但如果这是目标,请尝试以下操作:

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//swap jade for ejs etc

You'll need the res.renderlines when using a view engine as well. Something like this:

res.render使用视图引擎时也需要这些线。像这样的东西:

// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
    message: err.message,
    error: err
    });
  });
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  next(err);
  res.render('error', {
  message: err.message,
  error: {}
  });
});

回答by nivash-IoT

If you wish to render a html file use

如果您希望呈现 html 文件,请使用

response.sendfile('index.html');

then you remove of the

然后你删除

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

only thing is put your index.html in views. or make public folder as static and put the index.html in public

唯一的事情就是把你的 index.html 放在视图中。或将 public 文件夹设为静态并将 index.html 设为 public

回答by KARTHIKEYAN.A

set view engine following way

按照以下方式设置视图引擎

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

回答by Dinesh Rajan

If all that's needed is to send html code inline in the code, we can use below

如果只需要在代码中内联发送 html 代码,我们可以在下面使用

var app = express();
app.get('/test.html', function (req, res) {
   res.header('Content-Type', 'text/html').send("<html>my html code</html>");
});

回答by Chanoch

You can use express-error-handler to use static html pages for error handling and to avoid defining a view handler.

您可以使用 express-error-handler 使用静态 html 页面进行错误处理并避免定义视图处理程序。

The error was probably caused by a 404, maybe a missing favicon (apparent if you had included the previous console message). The 'view handler' of 'html' doesn't seem to be valid in 4.x express.

该错误可能是由 404 引起的,也可能是缺少网站图标(如果您包含了之前的控制台消息,则很明显)。“html”的“视图处理程序”在 4.x express 中似乎无效。

Regardless of the cause, you can avoid defining a (valid) view handler as long as you modify additional elements of your configuration.

无论原因如何,只要修改配置的其他元素,就可以避免定义(有效)视图处理程序。

Your options are to fix this problem are:

解决此问题的选项是:

  • Define a valid view handler as in other answers
  • Use send() instead of render to return the content directly
  • 像其他答案一样定义有效的视图处理程序
  • 使用 send() 而不是 render 直接返回内容

http://expressjs.com/en/api.html#res.render

http://expressjs.com/en/api.html#res.render

Using render without a filepath automatically invokes a view handler as with the following two lines from your configuration:

使用没有文件路径的渲染会自动调用视图处理程序,就像配置中的以下两行:

res.render('404', { url: req.url });

and:

和:

res.render('500);

Make sure you install express-error-handler with:

确保使用以下命令安装 express-error-handler:

npm install --save express-error-handler

Then import it in your app.js

然后将它导入你的 app.js

var ErrorHandler = require('express-error-handler');

Then change your error handling to use:

然后更改您的错误处理以使用:

// define below all other routes
var errorHandler = ErrorHandler({
  static: {
    '404': 'error.html' // put this file in your Public folder
    '500': 'error.html' // ditto
});

// any unresolved requests will 404
app.use(function(req,res,next) {
  var err = new Error('Not Found');
  err.status(404);
  next(err);
}

app.use(errorHandler);

回答by Mihnea

I just got this error message, and the problem was that I was not setting up my middleware properly.

我刚刚收到此错误消息,问题是我没有正确设置中间件。

I am building a blog in the MEANstack and needed body parsing for the .jadefiles that I was using on the front end side. Here is the snippet of code from my "/middleware/index.js" file, from my project.

我正在MEAN堆栈中构建一个博客,并且需要对我在前端使用的.jade文件进行正文解析。这是我的“ /middleware/index.js”文件中的代码片段,来自我的项目。

var express = require('express');
var morgan = require('morgan');
var session = require('express-session');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

module.exports = function (app) {
app.use(morgan('dev'));

// Good for now
// In the future, use connect-mongo or similar
// for persistant sessions
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(cookieParser());
app.use(session({secret: 'building a blog', saveUninitialized: true, resave: true}));

Also, here is my "package.json" file, you may be using different versions of technologies. Note: because I am not sure of the dependencies between them, I am including the whole file here:

另外,这是我的“ package.json”文件,您可能使用了不同版本的技术。注意:因为我不确定它们之间的依赖关系,所以我在这里包含了整个文件:

"dependencies": {
    "body-parser": "1.12.3",
    "consolidate": "0.12.1",
    "cookie-parser": "1.3.4",
    "crypto": "0.0.3",
    "debug": "2.1.1",
    "express": "4.12.2",
    "express-mongoose": "0.1.0",
    "express-session": "1.11.1",
    "jade": "1.9.2",
    "method-override": "2.3.2",
    "mongodb": "2.0.28",
    "mongoose": "4.0.2",
    "morgan": "1.5.1",
    "request": "2.55.0",
    "serve-favicon": "2.2.0",
    "swig": "1.4.2"
  }

Hope this helps someone! All the best!

希望这可以帮助某人!祝一切顺利!

回答by evanjmg

The above answers are correct, but I found that a simple typo can also generate this error. For example, I had var router = express() instead of var router = express.Router() and got this error. So it should be the following:

上面的答案是正确的,但我发现一个简单的错字也会产生这个错误。例如,我使用 var router = express() 而不是 var router = express.Router() 并收到此错误。所以它应该是以下内容:

// App.js 
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended:false}));
// assuming you put views folder in the same directory as app.js
app.set('views', __dirname + '/views')
app.engine('ejs', ejs.renderFile);
app.set('view engine', 'ejs');
// router - wherever you put it, could be in app.js
var router = express.Router();
router.get('/', function (req,res) {
  res.render('/index.ejs');
})

回答by jatin sablok

Just set view engine in your code.

只需在您的代码中设置视图引擎。

var app = express(); 
app.set('view engine', 'ejs');