我正在使用私有(private) api key 从外部数据库检索 JSON 对象。我使用express作为我的HTTP。我正在构建一个营养应用程序,它收集用户界面输入给出的食物列表。当返回多个食物对象时,会出现错误,即在将它们发送到客户端后我无法设置 header 。我的目标是当用户输入食物时有一个食物列表的下拉列表。
我尝试只限制一种食物对象的输出;没有错误发生。我尝试将食物对象设置为单独的对象数组,但错误仍然存在。如果发生先前的结果,我已确保使用 return 仅捕获一个响应,以防止执行其他快速路由。不确定这里的添加图像按钮在哪里,但这里是 fetchFoods.js 中输出的示例:
{ foodName: 'ARMADILLO EGGS, UPC: 732170002859',
foodNum: '45220998' }
{ foodName: 'ARMADILLO EGGS, UPC: 732170003856',
foodNum: '45201506' }
{ foodName: 'ARTESANIA, TOASTED ALMOND EGG NOUGHT, UPC: 815961010209',
foodNum: '45161494' }
...
但是,当从index.js执行时,就会出现错误。当提到我提到的错误时,只有在index.js 执行fetchFoods.js 时才会出现这种情况。否则,我可以直接从 fetchFoods.js 文件从数据库输出多个食物对象。
_http_outgoing.js:482
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:482:11)
就限制一种食物结果而言,从 fetchFoods.js 或 index.js 执行都不会发生错误。我认为我的问题出在我的快速配置上。我可以在我的终端和控制台中查看食物结果(仅当仅限于一个时),但如果有多个则无法查看。
编辑
这是原始的 JSON 对象:
list": {
"q": "eggs",
"sr": "1",
"ds": "any",
"start": 0,
"end": 25,
"total": 1956,
"group": "",
"sort": "n",
"item": [
{
"offset": 0,
"group": "Branded Food Products Database",
"name": "AHOLD, DEVILED EGG POTATO SALAD, UPC: 688267141584",
"ndbno": "45044170",
"ds": "LI",
"manu": "Ahold USA, Inc."
},
配置文件.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="icon" href="/img/app_logo.png"/>
<link rel="stylesheet" href="/css/styles.css">
<title>Profile</title>
</head>
<body>
<div class="main-content">
{{>header}}
<p>{{title}}</p>
<p>{{greeting}}</p>
<form>
<input placeholder="Search for foods">
<button>Search</button>
</form>
</div>
{{>footer}}
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js"></script>
<script src="/js/app.js"></script>
</body>
</html>
index.js
app.get('/fetchFoods', (req, res, next) => {
if (!req.query.food){
return res.send({
error: 'You must provide a food!'
});
}
next();
fetchFoods(req.query.food, (error, {foodName, foodNum} = {}) => {
if (error) {
return res.send({error});
} else {
return res.send({
foodName,
foodNum
});
}
});
});
app.js
const foodForm = document.querySelector('form');
const search = document.querySelector('input');
foodForm.addEventListener('submit', (e) => {
console.log('testing');
e.preventDefault();
const food = search.value;
fetch('http://localhost:3000/fetchFoods?food=' + food).then((response) => {
response.json().then((data) => {
if (data.error) {
console.log(data.error);
} else {
console.log(data.foodName);
console.log(data.foodNum);
}
}).catch(err => {
console.log("Error Reading data " + err);
});
});
});
app.listen(port, () => console.log(`Listening on port ${port}`));
fetchFoods.js
const request = require('request');
const fetchFoods = (food, callback) => {
const url = 'https://api.nal.usda.gov/ndb/search/?format=json&q=' + encodeURIComponent(food) + '&sort=n&max=25&offset=0&api_key=###';
request({url:url, json:true}, (error, {body}) => {
if (error) {
callback('Unable to connect to USDA database!', undefined);
} else if (body.errors) {
callback(body.errors.error[0].message);
}
var foodItem = body.list.item;
for (var i = 0; i < foodItem.length; i++){
callback(undefined, {
foodName: foodItem[i].name,
foodNum: foodItem[i].ndbno
});
}
});
};
fetchFoods('eggs', (error, data) => {
if (error) {
return console.log(error);
} else {
return console.log(data);
}
});
module.exports = fetchFoods;
package.json
{
"name": "nutrition-app-heroku",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "nodemon src/index.js -e js,hbs",
"dev": "nodemon src/index.js -e js,hbs"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"hbs": "^4.0.4",
"mongodb": "^3.2.7",
"mongoose": "^5.6.4",
"mustache": "^3.0.1",
"request": "^2.88.0",
"validator": "^11.1.0"
},
"devDependencies": {
"nodemon": "^1.19.1"
}
}
最佳答案
该错误表示您多次调用 res.send,只能发送一次。
我认为错误在这里:
for (var i = 0; i < foodItem.length; i++){
callback(undefined, {
foodName: foodItem[i].name,
foodNum: foodItem[i].ndbno
});
}
您应该发回该对象:
callback(undefined, foodItem);
然后将 foodItems 发送给客户端:
fetchFoods(req.query.food, (error, foodItems) => {
if (error) {
return res.send({error});
} else {
res.send(foodItems);
}
});
关于javascript - 从数据库检索多个 JSON 对象会导致 Express 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57435676/