Kesalahan: Tidak ada mesin default yang ditentukan dan tidak ada ekstensi yang disediakan

132

Saya bekerja melalui pengaturan server http menggunakan node.js dan engine. Namun, saya terus mengalami masalah yang saya punya sedikit informasi tentang bagaimana menyelesaikannya. Saya sangat menghargai bantuan untuk menyelesaikan masalah ini.

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)

Di bawah ini adalah apa yang saya siapkan untuk menghidupkan mesin ini.

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

Jawaban:

120

Barang res.render akan menimbulkan kesalahan jika Anda tidak menggunakan mesin tampilan.

Jika Anda hanya ingin melayani json, ganti res.render('error', { error: err });baris dalam kode Anda dengan:

res.json({ error: err })

PS: Orang biasanya juga memiliki pesan di objek yang dikembalikan:

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

Anda melewatkan mesin tampilan, misalnya menggunakan giok :

ubah-Mu

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

dengan

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

Jika Anda ingin menggunakan sintaks html friendly gunakan ejs

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

EDIT

Seperti yang Anda baca dari 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);
}

Anda harus menginstal a default engine

Expresscari tampilan tata letak standar program.templateseperti yang Anda baca di bawah:

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;

      }
    });

dan seperti yang Anda baca di bawah:

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

mesin tampilan default adalah jade

alessandro
sumber
2
Hai, bisakah Anda menjelaskan lebih lanjut bagaimana ini bekerja? Saya mulai membaca di node.js, berpikir itu yang saya butuhkan tetapi ketika saya masih tidak bisa menampilkan halaman saya, saya mencari tahu mengapa dan datang ke info di express. Sekarang saya mengikuti info di halaman 4.2 express, dan mengalami kesalahan di atas yang Anda bantu. Sekarang saya mendapatkan ejs dan sepertinya masih tidak semua yang saya butuhkan. Bisakah Anda memberi saya aliran bagaimana ini seharusnya berhasil?
Kobojunkie
Saya sarankan Anda untuk membaca tutorial ini langkah demi langkah utahjs.com/2010/09/25/nodejs-express-and-ejs-templates atau robdodson.me/blog/2012/05/31/how-to-use-ejs
alessandro
Saya pikir membaca bahwa pada Anda harus secara eksplisit menentukan tampilan mesin bahkan jika Anda melihat catatan rendering. itu tidak terjadi.
stevejpurves
15

Komentari res.renderbaris dalam kode Anda dan tambahkan next(err);saja. Jika Anda tidak menggunakan mesin tampilan, res.renderhal - hal itu akan menimbulkan kesalahan.

Maaf, Anda harus mengomentari baris ini juga:

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

Solusi saya akan menghasilkan tidak menggunakan mesin tampilan sekalipun. Anda tidak memerlukan mesin tampilan, tetapi jika itu tujuannya, coba ini:

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

Anda akan membutuhkan res.rendergaris saat menggunakan mesin tampilan juga. Sesuatu seperti ini:

// 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: {}
  });
});
caokey
sumber
12

Jika Anda ingin merender file html, gunakan:

response.sendfile('index.html');

Lalu Anda menghapus:

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

Masukan Anda *.htmldalam viewsdirektori, atau melayani publicdirektori sebagai statis dir dan menempatkan index.htmldi publicdir.

nivash-IoT
sumber
4
response.sendfile()sudah usang, gunakan response.sendFile()saja. Perhatikan modal itu "F".
Pramesh Bajracharya
6

atur tampilan engine dengan cara berikut

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
KARTHIKEYAN.A
sumber
4

Jika semua yang diperlukan adalah mengirim kode html sebaris dalam kode, kita dapat menggunakan di bawah ini

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

Saya baru saja menerima pesan kesalahan ini, dan masalahnya adalah saya tidak mengatur middleware saya dengan benar.

Saya sedang membangun sebuah blog di tumpukan MEAN dan perlu penguraian tubuh untuk file .jade yang saya gunakan di sisi depan. Ini adalah potongan kode dari file "/ middleware/index.js " saya, dari proyek saya.

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

Juga, inilah file " package.json " saya , Anda mungkin menggunakan berbagai versi teknologi. Catatan: karena saya tidak yakin dengan dependensi di antara mereka, saya menyertakan seluruh file di sini:

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

Semoga ini bisa membantu seseorang! Semua yang terbaik!

Mihnea
sumber
0

Jawaban di atas benar, tetapi saya menemukan bahwa kesalahan ketik yang sederhana juga dapat menghasilkan kesalahan ini. Sebagai contoh, saya punya var router = express () bukan var router = express.Router () dan mendapatkan kesalahan ini. Jadi harus sebagai berikut:

// 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');
})
evanjmg
sumber
0

Anda dapat menggunakan express-error-handler untuk menggunakan halaman html statis untuk penanganan kesalahan dan untuk menghindari mendefinisikan view handler.

Kesalahan mungkin disebabkan oleh 404, mungkin favicon yang hilang (jelas jika Anda telah memasukkan pesan konsol sebelumnya). 'View handler' dari 'html' tampaknya tidak valid dalam 4.x express.

Apa pun penyebabnya, Anda dapat menghindari mendefinisikan penangan tampilan (valid) selama Anda memodifikasi elemen tambahan dari konfigurasi Anda.

Pilihan Anda untuk memperbaiki masalah ini adalah:

  • Tetapkan penangan tampilan yang valid seperti pada jawaban lainnya
  • Gunakan kirim () alih-alih render untuk mengembalikan konten secara langsung

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

Menggunakan render tanpa filepath secara otomatis memanggil view handler seperti dengan dua baris berikut dari konfigurasi Anda:

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

dan:

res.render('500);

Pastikan Anda menginstal express-error-handler dengan:

npm install --save express-error-handler

Kemudian impor di app.js Anda

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

Kemudian ubah penanganan kesalahan Anda untuk menggunakan:

// 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);
Chanoch
sumber
0

Cukup setel view engine dalam kode Anda.

var app = express(); 
app.set('view engine', 'ejs');
jatin sablok
sumber
0

Kesalahan: Tidak ada mesin default yang ditentukan dan tidak ada ekstensi yang disediakan

Saya mendapat masalah yang sama (untuk melakukan proyek stack mean) .. masalahnya adalah saya tidak menyebutkan format untuk menginstal npm yaitu; pug atau jade, ejs dll. untuk mengatasi ini goto npm dan masukkan express --view = pug foldername. Ini akan memuat file pug yang diperlukan (index.pug, layout.pug dll.) Di folder yang Anda berikan.

Bhargava Gidijala
sumber
0

jika Anda mendapatkan kesalahan ini dengan menggunakan generator express, saya telah menyelesaikannya dengan menggunakan

express --view=ejs myapp

dari pada

express --view=pug myapp
Tiago da Silva Post
sumber