简体   繁体   English

如何将从控制器返回的数据传递到Express'路由器?

[英]How do I pass data returned from a controller to Express' router?

I'm trying to make a catch-all of sorts to return data to my Author endpoint. 我正在尝试进行各种各样的操作以将数据返回到Author端点。 If the url that is passed to the endpoint contains no query parameters, I want the router to return the full list of authors available. 如果传递给端点的url不包含查询参数,则我希望路由器返回可用作者的完整列表。 If the url contains firstName and lastName parameters, I want the controller to find the authors that match and, pass that data back to the router. 如果该URL包含firstName和lastName参数,则我希望控制器查找匹配的作者,然后将该数据传递回路由器。

Currently if I send the urls http://localhost:3001/authors or http://localhost:3001/authors?firstName=tom&lastName=dooly , I get an error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client . 目前,如果我发送网址http://localhost:3001/authorshttp://localhost:3001/authors?firstName=tom&lastName=doolyhttp://localhost:3001/authors?firstName=tom&lastName=dooly收到Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Can anyone tell me why this is happening and how to fix it? 谁能告诉我为什么会这样以及如何解决?

main: 主要:

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;

route: 路线:

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

You get cannot set headers after they are sent when you have two res.[whatever] s in your route. 当您的路由中有两个res.[whatever]时, cannot set headers after they are sent So you have res.send(functionCallThatAlsoDoesRes.Send) . 所以你有res.send(functionCallThatAlsoDoesRes.Send) That's what's causing the error. 这就是导致错误的原因。

If you want a route to take multiple actions between the request and the response, you can write those as separate middlewares. 如果您希望路由在请求和响应之间采取多种措施,则可以将其编写为单独的中间件。 Middlewares always take the arguments req , res , and next (a function that says to go to the next middleware in the list). 中间件始终采用参数reqresnext (该函数表示将转到列表中的下一个中间件)。

So, you might write: 因此,您可以这样写:

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

Then in your route, you'd say: 然后在您的路线中,您会说:

router.get('/', authorController.findAuthorsByFirstAndLastName, authorController.author_list, (req, res) => {
    res.json({ authors: res.locals.authors })
})

If you haven't seen res.locals before, it's just a property on the response object that is available for you to attach things to. 如果您以前没有看过res.locals ,那么它只是响应对象上的一个属性,可用于附加内容。 It persists throughout the request/response cycle and is cleared for each new request. 它在请求/响应周期中一直存在,并为每个新请求清除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将参数传递给 express.js 路由器? - How do I pass a parameter to express.js Router? 如何在 node.js 中将数据从控制器传递到路由器? - How to pass data from controller to router in node.js? 带Express的EJS-我无法将数据从路由器传递到View,但是我仍然收到ReferenceError msg - EJS with Express - i cant pass data from router to View but i still i get ReferenceError msg 如何访问从 MVC 视图中的 ajax 调用调用的控制器返回的数据 - How do I access data returned from a controller invoked by an ajax call in an MVC View 在角度js中,如何将数据从父控制器传递到子控制器? - In angular js, How do I pass data from a parent controller to a child controller? 如何通过 props 从 React Router 传递数据? 我做不到 - How to pass Data From React Router through props? I am unable to do it 如何使用 React Router 将数据从一个兄弟姐妹传递到另一个兄弟姐妹? - How do I pass data from one sibling to another using React Router? 如何使用 Vue 路由器将数据传递给另一个组件? - How do I pass data to another component using Vue router? 如何将JSON对象从控制器传递到路由器? - How to pass json object from controller to router? 如何获取从ajax中的Controller返回的模型的值? - How do I get the values of the model returned from Controller in ajax?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM