基本上,我通过Node.js和Express(我是初学者)设置一个Web服务器,通过读取JSON文件来检索数据。 例如,这是我的data.json文件:
[{
"color": "black",
"category": "hue",
"type": "primary"
},
{
"color": "red",
"category": "hue",
"type": "primary"
}
]
我试图通过实现此代码来检索所有颜色,以便在localhost上显示:
router.get('/colors', function (req, res) {
fs.readFile(__dirname + '/data.json', 'utf8', function (err, data) {
data = JSON.parse(data);
res.json(data); //this displays all of the contents of data.json
})
});
router.get('/colors:name', function (req, res) {
fs.readFile(__dirname + '/data.json', 'utf8', function (err, data) {
data = JSON.parse(data);
for (var i = 0; i < data.length; i++) {
res.json(data[i][1]); //trying to display the values of color
}
})
});
我该怎么做?
答案 0 :(得分:2)
一旦你把它分解成更小的问题,你想要做的事情实际上非常简单。这是打破它的一种方法:
var data = [];
try {
data = JSON.parse(fs.readFileSync('/path/to/json'));
} catch (e) {
// Handle JSON parse error or file not exists error etc
data = [{
"color": "black",
"category": "hue",
"type": "primary"
},
{
"color": "red",
"category": "hue",
"type": "primary"
}
]
}
router.get('/colors', function (req, res, next) {
var colors = data.map(function (item) {
return item.color
}); // This will look look like: ["black","red"]
res.json(colors); // Send your array as a JSON array to the client calling this API
})
此方法的一些改进:
Array.prototype.map
Docs从对象中提取颜色数组。注意:
您可以根据需要构建颜色数组,并将其作为JSON发送到该结构中。
示例:
var colors = data.map(function(item){return {color:item.color};}); // [{"color":"black"},{"color":"red"}]
var colors = {colors: data.map(function(item){return item.color;})} // { "colors" : ["black" ,"red"] }
代码中的一些问题:
res.json
这是不正确的,因为响应应该只发送一次。理想情况下,您可以通过迭代数据并使用res.json
(我在内部猜测JSON.stringify
对象并将其作为设置正确的标题后的响应)答案 1 :(得分:1)
在快递中,你可以这样做
router.get('/colors/:name', (req, res) => {
const key = req.params.name
const content = fs.readFileSync(__dirname + '/data.json', 'utf8')
const data = JSON.parse(content)
const values = data.reduce((values, value) => {
values.push(value[key])
return values
}, [])
// values => ['black', 'red']
res.send(values)
});
然后curl http://localhost/colors/color
,
你可以得到[&#39; black&#39;,&#39; red&#39;]
答案 2 :(得分:0)
您要做的是:
res.json(data[i]['color']);
答案 3 :(得分:0)
如果你真的不想使用json中的键,你可能想要使用Object.values
函数。
...
data = JSON.parse(data)
var values = []
for (var i = 0; i < data.length; i++) {
values.push(Object.values(data[i])[0]) // 0 - color, 1 - category, 2 - type
}
res.json(values) // ["black","red"]
...
答案 4 :(得分:0)
你绝不能在生产中使用fs.readFileSync
。任何同步函数都会阻止事件循环,直到执行完成,因此在之后延迟所有内容(如果认为有必要,请谨慎使用)。几天前,我自己遇到了最糟糕的经历,并以一种艰难的方式学到了这一点。
在快递中,您可以使用param
或query
定义路线,并将其用于map
fs.readFile
回调函数内的内容。
/**
* get color by name
*
* @param {String} name name of the color
* @return {Array} array of the color data matching param
*/
router.get('/colors/:name', (req, res) => {
const color = req.params.name
const filename = __dirname + '/data.json';
fs.readFile('/etc/passwd', 'utf8', (err, data) => {
if(err){
return res.send([]); // handle any error returned by readFile function here
}
try{
data = JSON.parse(data); // parse the JSON string to array
let filtered = []; // initialise empty array
if(data.length > 0){ // we got an ARRAY of objects, right? make your check here for the array or else any map, filter, reduce, forEach function will break the app
filtered = data.filter((obj) => {
return obj.color === color; // return the object if the condition is true
});
}
return res.send(filtered); // send the response
}
catch(e){
return res.send([]); // handle any error returned from JSON.parse function here
}
});
});
总而言之,使用fs.readFile
异步函数,以便事件循环不会被阻塞。在回调内部解析内容,然后return
响应。 return
非常重要,否则您最终可能会收到错误:发送后无法设置标题
免责声明以上代码未经测试但应该有效。这只是为了证明这个想法。
答案 5 :(得分:-1)
我认为没有密钥你就无法访问JSON。您可以使用Foreach循环(var name:object){}检查foreach它可能对您有所帮助