Node.js “接收”;错误:Can';t在发送标题后设置标题。”;进行多个API调用时
我正在重构一个Express项目,我需要进行多个API调用。我目前有9个单独的函数来进行每个单独的API调用,然后在每次API调用后将其设置为res.locals 我已经创建了一个数组,其中包含我需要访问的所有API URL,然后我有一个函数,该函数遍历该数组以进行所有的获取调用。但是,当我收到下面的消息时,我遇到了设置标题以使JSON数据能够通过的问题:Node.js “接收”;错误:Can';t在发送标题后设置标题。”;进行多个API调用时,node.js,api,express,Node.js,Api,Express,我正在重构一个Express项目,我需要进行多个API调用。我目前有9个单独的函数来进行每个单独的API调用,然后在每次API调用后将其设置为res.locals 我已经创建了一个数组,其中包含我需要访问的所有API URL,然后我有一个函数,该函数遍历该数组以进行所有的获取调用。但是,当我收到下面的消息时,我遇到了设置标题以使JSON数据能够通过的问题: 错误:发送邮件后无法设置邮件头。 根据我设置控制器的方式,我可以获取要在页面上呈现的控制器标头和第一个API响应,也可以仅获取要呈现的控制器
错误:发送邮件后无法设置邮件头。
根据我设置控制器的方式,我可以获取要在页面上呈现的控制器标头和第一个API响应,也可以仅获取要呈现的控制器标头。考虑到我的情况,我还没有找到解决这个问题的办法,我想知道是否有人提出了纠正这个问题的建议。我已经粘贴了我认为应该足够解决问题的代码,但是如果还有什么我可以提供的,请告诉我
API帮助文件(进行API调用的位置):
引入路由的服务器文件:
const cryptoRouter = require('./routes/crypto-routes')
app.use('/', cryptoRouter)
没有命中模型文件,因为此时数据库中没有插入任何内容。好的,这里有一个问题:
function getData(req, res, next) {
for (let i = 0; i < links.length; i ++) {
fetch(links[i])
.then(res => res.json())
.then(fetchRes => {
res.locals.i = fetchRes
next()
})
.catch(err => {
res.json({err})
})
}
}
然后,在您的.get()
路由处理程序中,我不知道您试图实现的结果类型的确切原因,但要返回结果数组,您可以执行以下操作:
cryptoController.sendApiData = (req, res) => {
console.log(res.locals.data)
res.json({
message: 'data returned for crypto',
data: res.locals.data
});
}
您必须为该控制器代码(整个请求处理程序以及在该请求处理程序中执行的任何代码)显示更多上下文,因为在这里显示它是没有意义的。您处于
for
循环中,将自定义函数分配给cryptoController.sendApiData
,但不执行任何操作。另外,给同一个变量分配10个不同的函数也没有好处。只有最后一个将实际分配。另外,您也不会显示任何实际执行cryptoController.sendApiData()
的代码。您看到的错误的一般原因是针对给定请求发送多个响应的代码。您只能发送一个响应。例如,对于给定的请求,只能调用res.json()
一次。第一次调用它时,数据被转换为JSON,发送到客户机并关闭http连接。无法发送更多数据。如果我理解正确,我甚至无法使用异步函数来发送数据?异步函数与此无关。你真的需要向我们展示更多的代码,并描述你试图为我们做些什么,以更具体地帮助你。明白了。我刚刚更新了我的原始帖子,以显示路由和完整的控制器文件,以及如何在server.js文件中启动路由。澄清一下:我目前有9个API调用正在获得它们自己的函数(总共9个函数)。我正在尝试重构,以便所有API调用都可以在一个函数中进行,从而减少编写的代码量。非常感谢您的回复,并让我知道是否有任何其他信息/澄清我可以发送。这成功了!非常感谢你在这方面的帮助,有一段时间我真的对承诺感到困惑,但这个解释只是让它有点点击。
// import model
const Crypto = require('../models/Crypto')
// initiate controller object
const cryptoController = {}
// find latest cap coin entry
cryptoController.latest = (req, res, next) => {
Crypto.findRecent()
.then(crypto => {
res.json({
message: 'retrieved entry',
data: { crypto }
})
}).catch(next)
}
// send api data
// for (let i = 0; i < 10; i ++) {
cryptoController.sendApiData = (req, res) => {
console.log(res.locals)
res.json({
message: 'data returned for crypto',
i: res.locals.i
})
// }
}
// create new entry
cryptoController.create = (req, res) => {
console.log(req.body, ' req.body from cryptoController#create')
Crypto.create({
// time made
time_made: Date.now(),
// crypto data
usd: req.body.usd,
us_high: req.body.us_high,
us_low: req.body.us_low,
eur: req.body.eur,
eur_high: req.body.eur_high,
eur_low: req.body.eur_low,
trades: req.body.trades,
one_hour: req.body.one_hour,
one_day: req.body.one_day,
seven_days: req.body.Seven_days,
crypto_id: req.body.crypto_id
})
}
module.exports = cryptoController
// import dependencies
const express = require('express')
const cryptoController = require('../controllers/crypto-controller')
const cryptoHelpers = require('../services/crypto-helpers')
// set router variable
const cryptoRouter = express.Router()
// set routes to fetch and store API data
cryptoRouter.post('/crypto', cryptoHelpers.getData, cryptoController.create)
cryptoRouter.get('/crypto', cryptoHelpers.getData, cryptoController.sendApiData)
module.exports = cryptoRouter;
const cryptoRouter = require('./routes/crypto-routes')
app.use('/', cryptoRouter)
function getData(req, res, next) {
for (let i = 0; i < links.length; i ++) {
fetch(links[i])
.then(res => res.json())
.then(fetchRes => {
res.locals.i = fetchRes
next()
})
.catch(err => {
res.json({err})
})
}
}
function getData(req, res, next) {
let promises = links.map(function(link) {
return fetch(link).then(res => res.json())
});
Promise.all(promises).then(results => {
res.locals.data = results; // res.locals.data is an array of link json
next();
}).catch(err => {
res.status(500).json({err});
});
}
cryptoController.sendApiData = (req, res) => {
console.log(res.locals.data)
res.json({
message: 'data returned for crypto',
data: res.locals.data
});
}