Помилка: двигун за замовчуванням не вказано і розширення не надано


132

Я працюю над налаштуванням http-сервера за допомогою node.js та engine. Однак я все ще стикаюся з питаннями, які мають мало інформації про те, як вирішити, я б вдячний допомогти у вирішенні цього питання.

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)

Нижче наведено те, що я створив для запуску цього двигуна.

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

Відповіді:


120

Інформація про рецензування призведе до помилки, якщо ви не використовуєте механізм перегляду.

Якщо ви просто хочете обслуговувати json, замініть res.render('error', { error: err });рядки у своєму коді на:

res.json({ error: err })

PS: Люди зазвичай також мають повідомлення у поверненому об'єкті:

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

102

Вам не вистачає двигуна перегляду, наприклад, використовуйте нефрит :

змінити своє

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

з

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

Якщо ви хочете використовувати замість синтаксису HTML, використовуйте замість ejs

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

EDIT

Як ви можете прочитати з view.js Модуль експрес-перегляду

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

Ви повинні встановити default engine

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;

      }
    });

і як ви можете прочитати нижче:

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

двигуном подання за замовчуванням є jade


2
Привіт, ви можете далі пояснити, як це працює? Я почав читати на node.js, думаючи, що це все, що мені потрібно, але коли я все ще не зміг відобразити свої сторінки, я подивився, чому і перейшов до інформації про експрес. Тепер я стежив за інформацією на експрес-сторінці 4.2 та наткнувся на помилку, над якою ви допомогли. Тепер я отримав ejs, і все ще, здається, це не все, що мені потрібно. Чи можете ви, будь ласка, дати мені інформацію про те, як це повинно працювати, будь ласка?
Кобожункі

Я рекомендую прочитати цей покроковий посібник utahjs.com/2010/09/25/nodejs-express-and-ejs-templates або цей robdodson.me/blog/2012/05/31/how-to-use-ejs -in-express
алессандро

Я думав, читаючи, що у вас необхідно чітко визначити двигун перегляду, навіть якщо ви помічаєте подання переглядів. але це не так.
stevejpurves

15

Прокоментуйте res.renderрядки у своєму коді та додайте next(err);замість цього. Якщо ви не використовуєте механізм перегляду, цей res.renderматеріал призведе до помилки.

Вибачте, вам також доведеться прокоментувати цей рядок:

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

Моє рішення призведе до того, що я не використовую механізм перегляду. Вам не потрібен механізм перегляду, але якщо це мета, спробуйте:

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

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: {}
  });
});

12

Якщо ви хочете надати HTML-файл, використовуйте:

response.sendfile('index.html');

Потім ви видаляєте:

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

Помістіть свій *.htmlв viewsкаталозі, або служити publicкаталог як статичний каталог і поставити index.htmlв publicрідше.


4
response.sendfile()застаріло, response.sendFile()замість цього використовуйте . Зауважте, що капітал "F".
Прамеш Байрачаря

6

встановити перегляд двигуна наступним чином

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

4

Якщо все, що потрібно, - це надіслати html-код, вбудований в код, ми можемо використовувати нижче

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

0

Щойно я отримав це повідомлення про помилку, і проблема полягала в тому, що я не правильно налаштував своє проміжне програмне забезпечення.

Я будую блог у стеці 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}));

Також ось мій файл " 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"
  }

Сподіваюся, це допоможе комусь! Всього найкращого!


0

Наведені вище відповіді правильні, але я виявив, що проста помилка друку також може генерувати цю помилку. Наприклад, у мене був 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');
})

0

Ви можете використовувати експрес-оброблювач помилок, щоб використовувати статичні HTML-сторінки для обробки помилок та уникати визначення обробника перегляду.

Помилка, ймовірно, була спричинена 404, можливо, відсутнім фавіконом (очевидно, якщо ви включили попереднє повідомлення консолі). Здається, що обробник перегляду "html" не відповідає дійсності в 4.x виразі.

Незалежно від причини, ви можете уникнути визначення (дійсного) обробника перегляду, якщо ви змінюєте додаткові елементи своєї конфігурації.

Ви можете вирішити цю проблему:

  • Визначте дійсний обробник перегляду, як і в інших відповідях
  • Використовуйте send () замість візуалізації, щоб повернути вміст безпосередньо

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

Використання візуалізації без шляху до файлу автоматично викликає обробник представлення даних, як у наступних двох рядках з вашої конфігурації:

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

і:

res.render('500);

Обов’язково встановіть експрес-обробник помилок за допомогою:

npm install --save express-error-handler

Потім імпортуйте його у ваш app.js

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

Потім змініть обробку помилок на використання:

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


0

Помилка: двигун за замовчуванням не вказано і розширення не надано

У мене така ж проблема (для виконання проекту середнього стеку) .. Проблема в тому, що я не згадав формат для встановлення npm, тобто; мопс або нефрит, ejs тощо, щоб вирішити цей goto npm і ввести Express --view = ім'я папки. Це завантажить необхідні файли мопсів (index.pug, layout.pug і т. Д.) В папці заданої ури.


0

якщо ви отримали цю помилку за допомогою генератора експресів, я вирішив її за допомогою

express --view=ejs myapp

замість

express --view=pug myapp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.