我正在尝试进行各种包罗万象的操作,以将数据返回到我的作者端点。如果传递到端点的 url 不包含查询参数,我希望路由器返回可用作者的完整列表。如果 url 包含firstName 和lastName 参数,我希望 Controller 找到匹配的作者,并将该数据传递回路由器。
目前,如果我发送网址 http://localhost:3001/authors
或 http://localhost:3001/authors?firstName=tom&lastName=dooly
,我收到错误错误 [ERR_HTTP_HEADERS_SENT]:将 header 发送到客户端后无法设置 header
。
谁能告诉我为什么会发生这种情况以及如何解决它?
主要:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
var dev_db_url = 'mongodb://localhost:27017/'
var mongoDB = process.env.MONGODB_URI || dev_db_url;
mongoose.connect(dev_db_url);
mongoose.Promise = global.Promise;
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
var index = require('./routes/index');
var users = require('./routes/users');
var feedEntries = require('./routes/feedEntries');
var authors = require('./routes/authors');
app.use('/', index);
app.use('/users', users);
app.use('/feedEntries', feedEntries);
app.use('/authors', authors);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not not Found');
err.status = 404;
next(err);
});
app.use(function(err, req, res, next) {
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
路线:
var express = require('express');
var router = express.Router();
var authorController = require('../controllers/authorController');
authorController.findAuthorsByFirstAndLastName);
router.get('/', function (req, res) {
if(req.query.firstName||req.query.lastName) {
res.send(authorController.findAuthorsByFirstAndLastName(req,res));
}else{
res.send(authorController.author_list(req,res));
}
});
module.exports = router;
Controller :
var Author = require('../models/author')
var async = require('async')
exports.author_list = function(req, res, next) {
Author.find({},function(err, authors) {
if (err){
res.send(err);
}
return.json(authors);
});
};
exports.findAuthorsByFirstAndLastName = function (req, res, next){
var query = {}
if(req.query.firstName||req.query.lastName) {
query = {$or:[{firstName:{$regex: req.query.firstName, $options: 'i'}},
{lastName:{$regex: req.query.lastName, $options: 'i'}}]}
}
else {
return res.status(500).send({ error: 'Unable to parse data'});
}
var firstName = req.body.firstName;
var lastName = req.body.lastName;
Author.find(query , function (err, authors) {
if(err) {
res.send(err);
}
res.json(authors);
});
};
最佳答案
当您的路由中有两个 res.[whatever]
时,您会收到无法在发送后设置 header
。所以你有res.send(functionCallThatAlsoDoesRes.Send)。这就是导致错误的原因。
如果您希望路由在请求和响应之间执行多个操作,您可以将它们编写为单独的中间件。中间件始终采用参数 req
、res
和 next
(一个表示转到列表中下一个中间件的函数)。
所以,你可以这样写:
authorController.findAuthorsByFirstAndLastName = function(req, res, next) {
if (!(req.query.firstName || req.query.lastName)) {
res.locals.getFullAuthorList = true
return next()
} else {
const query = /* whatever */
Author.find(query, (err, authors) => {
if (err) return next(err)
res.locals.authors = authors
next()
})
}
}
authorController.author_list = function(req, res, next) {
if (!res.locals.getFullAuthorList) return next() // if we already have authors we don't need to do anything
Author.find({}, (err, authors) => {
if (err) return next(err)
res.locals.authors = authors
next()
})
}
然后在你的 route ,你会说:
router.get('/', authorController.findAuthorsByFirstAndLastName, authorController.author_list, (req, res) => {
res.json({ authors: res.locals.authors })
})
如果您以前没有见过 res.locals
,它只是响应对象上的一个属性,可供您附加内容。它在整个请求/响应周期中持续存在,并针对每个新请求而清除。
关于javascript - 如何将从 Controller 返回的数据传递到 Express 路由器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49369121/