当前位置: 首页 > 知识库问答 >
问题:

当我尝试发出更新请求时,无法在发送到客户端后设置标头

谈旺
2023-03-14

我正试图创造一个垃圾。我已经创建了更新,但是当我尝试从postman请求时,我得到以下错误:

错误 [ERR_HTTP_HEADERS_SENT]: 在服务器响应.set 上将标头发送到客户端后无法设置标头 (_http_outgoing.js:526:11) 在服务器响应..node_modules (E:\freebooks-core-api\node_modules node_modules\express\lib\响应.js.js:267:10) 在服务器响应.send(E:\免费书-核心-api\node_modules\express\lib\响应.js:170:12) 在 ServerResponse.send (E:\freebooks-core-api\node_modules\express\lib\response.js:158:21) at Object.export.success (E:\freebooks-core-api\网络\响应.js:3:6) 在 E:\freebooks-core-api\components\书籍\网络.js:32:18 在进程中ticksAndRejections(内部/进程/task_queues.js:97:5) { 代码: 'ERR_HTTP_HEADERS_SENT' } (节点:2844) 未处理的概率警告:错误 [ERR_HTTP_HEADERS_SENT]:在服务器发送到客户端后无法设置标头服务器响应.setHeader (_http_outgoing.js:526:11) 在 ServerResponse.header (E:\freebooks-core-api\node_modules\express\lib\响应.js:771:10) at ServerResponse.send (E:\freebooks-core-api\node_modules\express\lib\response.js:170:12) 在 ServerResponse.json (E:\freebooks-core-api\node_modules\express\lib\响应.js.js:267:15) 在 ServerResponse.send(E:\freebooks-core-api node_modules\components\书籍\网络\响应.js.js:34:16 在进程中注释和回词 (内部/进程/task_queues.js:97:5) (节点:2844) 未处理的promise拒绝警告: 未处理的promise拒绝。此错误起源于在没有 catch 块的情况下抛入异步函数内部,或者拒绝未使用 .catch() 处理的promise。要在未处理的 promise 拒绝时终止节点进程,请使用 CLI 标志 --未处理的拒绝 = 严格(请参见 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。(拒绝 ID: 1) (节点:2844) [DEP0018] 弃用警告:不推荐使用未处理的promise拒绝。将来,未处理的promise拒绝将使用非零退出代码终止 Node.js 进程。

正如我在错误中读到的,这来自以下文件:

回答我的网络文件夹中的js

exports.success = function (req, res, data, status) {
  res.status(status || 200)
    .send({
      error: '',
      data
    })
}

exports.error = function (req, res, error, status, log) {
  console.log(log)
  res.status(status || 500)
    .send({
      error,
      data: ''
    })
}

和网络.js在我的书(组件)文件夹中:

const router = require('express').Router()
const response = require('../../network/response')
const controller = require('./controller')

router.get('/', function (req, res) {
    controller.getBooks()
        .then( data => {
            response.success(req, res, data, 200)
        })
        .catch( err => {
            response.error(req, res, 'Unexpected Error', 500, err)
        })
})

router.post('/', function (req, res) {
  const book = req.body
  console.log(book)
  controller.addBook(book).then( data => {
    response.success(req, res, book, 201)
  })
    .catch(err => {
      response.error(req, res, 'Internal error', 500, err)
    })
})

router.patch('/:id', function(req, res) {
  const { id } = req.params
  console.log(id)
  const book = req.body
  controller.updateBook(id, book)
    .then( data => {
        response.success(req, res, data, 200)
    }).catch( err => {
      response.error(req, res, 'Internal error', 500, err)
    }) 
  res.send('Ok')
})

module.exports = router

但是由于我正在调用控制器并且错误正在该行上运行,因此这是代码:

const store = require('./store')

function getBooks () {
  return new Promise((resolve, reject) => {

    resolve(store.list())
  })
}

function addBook (book) {
  return new Promise((resolve, reject) => {
    if (!book) {
      reject('I reject')
      return false
    } else {

      resolve(book)
      store.add(book)
    }
  })
}

 function updateBook (id, book) {
  return new Promise( async (resolve, reject) => {
      if (!id || !book) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id, book)
        resolve(result)
      }

  })
}

function deleteBook (id) {
  return new Promise( async (resolve, reject) => {
      if (!id) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id)
        resolve(result)
      }

  })
}

module.exports = {
  addBook,
  getBooks,
  updateBook,
  deleteBook
}

最后是商店

const db = require('mongoose')
const Model = require('./model')

db.Promise = global.Promise
db.connect(`mongodb+srv://fewtwtwfwe:efwefwecwecw@ferwrtervsefwg/test?retryWrites=true&w=majority`, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then( () => {
    console.log(`Database connected`)
}).catch( err => {
    console.error(err)
})

function addBook(book) {
    const myBook = new Model(book)
    myBook.save()
}

async function getBooks() {
   const books =  await Model.find()
   return books
}

async function updateBook(id, book) {
    const foundBook = await Model.findOne({
        '_id':id
    })
    foundBook.book = book
    const newBook = await foundBook.save()
    return newBook
}

async function deleteBook(id) {
    const foundBook = await Model.findOne({
        '_id':id
    })
}


module.exports = {
    add: addBook,
    list: getBooks,
    update: updateBook,
    delete: deleteBook,
}

我修改了与数据库连接的数据,因为我确信错误不在那里,我提出了其他请求,显然一切都很好。有什么想法吗?

共有1个答案

唐麒
2023-03-14

对于每个传入的请求,您只能发送一个响应。这个特定的错误消息告诉您,您的代码正在尝试发送两个请求。大多数情况下,这是由于具有异步函数的代码顺序不正确造成的。在这个html" target="_blank">路由中似乎就是这种情况:

router.patch('/:id', function(req, res) {
  const { id } = req.params
  console.log(id)
  const book = req.body
  controller.updateBook(id, book)
    .then( data => {
        response.success(req, res, data, 200)
    }).catch( err => {
      response.error(req, res, 'Internal error', 500, err)
    }) 
  res.send('Ok')
})

首先它执行:

controller.updateBook()

当异步操作运行时,它会执行:

res.send('Ok');

然后,过一段时间,< code>updateBook()完成并调用< code >。then()或< code >。catch()处理程序,然后尝试对同一请求发送另一个响应。

看来您应该删除res。send('Ok')完全是因为您希望根据updateBook()的状态发送响应。然后是()。catch()处理程序。

在一个完全独立的主题中,像在updateBook()中一样,在另一个promise中包装promise返回函数有点反模式。我建议你改变这一点:

function updateBook (id, book) {
  return new Promise( async (resolve, reject) => {
      if (!id || !book) {
          reject('Invalid data')
          return false
      } else {
        const result = await store.update(id, book)
        resolve(result)
      }

  })
}

到此:

function updateBook (id, book) {
    if (!id || !book) {
        return Promise.reject('Invalid data');
    } else {
        return store.update(id, book);
    }
}

仅供参考,它是反模式的原因是它是不必要的代码,而且人们经常在错误处理中出错,这正是您所做的。如果存储。update()被拒绝,您没有围绕等待try/catchforcatch,因此它可能会丢失,您的promise永远不会得到解决或拒绝。

您应该更改所有结构类似的函数来解决此问题。

 类似资料:
  • 我正在关注一个关于udemy上的节点.js的课程,这有点过时了,遇到了这些错误,我无法找到解决方案。 我尝试了什么: 使用next(); 在所有if语句中添加返回res 有人能帮我修一下这些吗?我将不胜感激! 提前感谢! 用户名存在错误:错误 [ERR_HTTP_HEADERS_SENT]:在服务器响应.set 上将标头发送到客户端后无法设置标头 (_http_outgoing.js:526:11

  • 问题内容: 将标头发送到客户端后,无法设置标头。这是请求验证后的后端错误,看起来像标头问题。我为我的项目脏代码感到抱歉,我还需要做其他事情,因此在注释中有一些代码。这是我的代码 您可以在我的代码中发现其他错误,因为我尝试了许多不同的方法。这是passport.js配置文件 这是身份验证的ajax请求 非常感谢你。 问题答案: 这是由于您的代码试图从authenticate函数发送多个响应。 删除其

  • 将标头发送到客户端后,无法对其进行设置。这是我的身份验证post请求后的后端错误。看起来标题有问题。我很抱歉我的项目肮脏的代码,我需要做一些别的事情,所以有一些代码在评论中。这是我的代码 你可以在我的代码中找到其他错误,因为我尝试了许多不同的方法。以下是passport.js配置文件 这是用于身份验证的 ajax 请求 非常感谢。

  • 我在NodeJS中使用Passport.js、Express和Mongoose时遇到了这个奇怪的问题。基本上,即使我只发送了一个头,我还是得到一个错误,说“不能在头被发送到客户端后设置它们”。 我读过其他帖子并尝试过,但没有一个有效。 应用程序。get-res.send与return res.send之间有什么区别吗 错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后,无法设

  • 首先,我为拼写错误道歉,我是巴西人 我访问了下面的问题,但它没有帮助我解决问题 ERR_HTTP_HEADERS_SENT:将标头发送到客户端后,无法设置标头 我有一个方法,我从路由调用在第一个请求,它按预期工作 但在下一个命令中,它返回以下错误 我的代码 我尝试使用失败 这个方法返回一个从excel电子表格中读取的对象 服务器我的代码出错

  • 问题内容: 我对Node.js相当陌生,遇到了一些问题。 我正在使用Node.js 4.10和Express 2.4.3。 当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将重定向到http://127.0.0.1:8888/auth/facebook_callback。 然后,我收到以下错误: 以下是我的代码: 我可以知道我的代码有什么问题吗? 问题答案: