如何在没有密钥的情况下访问JSON文件的内容?

如何在没有密钥的情况下访问JSON文件的内容?,json,node.js,express,Json,Node.js,Express,基本上,我通过Node.js和Express(我是这方面的初学者)设置一个web服务器,通过读取JSON文件来检索数据。 例如,这是我的data.json文件: [{ "color": "black", "category": "hue", "type": "primary" }, { "color": "red", "category": "hue", "type": "primar

基本上,我通过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
        }
    })
});
router.get('/colors',函数(req,res){
fs.readFile(uuu dirname+'/data.json',utf8',函数(err,data){
data=JSON.parse(数据);
res.json(data);//显示data.json的所有内容
})
});
router.get('/colors:name',函数(req,res){
fs.readFile(uuu dirname+'/data.json',utf8',函数(err,data){
data=JSON.parse(数据);
对于(变量i=0;i

我该怎么做呢?

您希望做的是:

res.json(data[i]['color']);

您希望做的是:

res.json(data[i]['color']);

我认为没有密钥就无法访问JSON。您可以使用Foreach循环for(var name:object){}检查Foreach它可能会帮助您

我认为没有键您无法访问JSON。您可以使用Foreach循环for(var name:object){}检查Foreach它可以帮助您

在express中,您可以这样做

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)
});
然后
curlhttp://localhost/colors/color


您可以在express中获得['black'、'red']

,您可以这样做

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)
});
然后
curlhttp://localhost/colors/color


如果你不想使用json中的键,你可以得到['black','red']

,你可以使用
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"]
...
/** 
* 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
    }
  });

});
。。。
data=JSON.parse(数据)
var值=[]
对于(变量i=0;i
如果您真的不想使用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"]
...
/** 
* 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
    }
  });

});
。。。
data=JSON.parse(数据)
var值=[]
对于(变量i=0;i
一旦你把它分解成更小的问题,你想做的事情实际上相当简单。以下是一种分解方法:

  • 将JSON数据加载到内存中供API使用
  • 定义一个API路由,该路由仅从JSON数据中提取颜色,并将其作为JSON发送给客户端

  • 此方法的一些改进:

  • 当应用程序启动并且数据缓存在内存中以供将来使用时,该文件只同步读取一次
  • 使用
    Array.prototype.map
    从对象中提取颜色数组

  • 注:

    您可以随意构造颜色数组,并在该结构中将其作为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"] }
    

    您的代码中存在一些问题:

  • 您正在for循环中使用
    res.json
    ,这是不正确的,因为响应只应发送一次。理想情况下,您可以通过迭代数据在需要的结构中构建JS对象,并使用
    res.json
    发送完成的对象一次(我在内部猜测是
    json.stringify
    s对象,并在设置正确的头后将其作为响应发送)
  • 读取文件是一项昂贵的操作。如果您能够读取一次数据并将其缓存在内存中,那么这将是非常有效的(前提是您的数据不会太大—在这种情况下,使用文件存储信息可能一开始就效率低下)

  • 一旦你把它分解成更小的问题,你想要做的其实很简单。以下是一种分解方法:

  • 将JSON数据加载到内存中供API使用
  • 定义一个API路由,该路由仅从JSON数据中提取颜色,并将其作为JSON发送给客户端

  • 此方法的一些改进:

  • 当应用程序启动并且数据缓存在内存中以供将来使用时,该文件只同步读取一次
  • 使用
    Array.prototype.map
    从对象中提取颜色数组

  • 注:

    您可以随意构造颜色数组,并在该结构中将其作为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"] }
    

    您的代码中存在一些问题:

  • 您正在for循环中使用
    res.json
    ,这是不正确的,因为响应只应发送一次。理想情况下,您可以通过迭代数据在需要的结构中构建JS对象,并使用
    res.json
    发送完成的对象一次(我在内部猜测是
    json.stringify
    s对象,并在设置正确的头后将其作为响应发送)
  • 读取文件是一项昂贵的操作。如果您能够读取一次数据并将其缓存在内存中,那么这将是非常有效的(前提是您的数据不会太大—在这种情况下,使用文件存储信息可能一开始就效率低下)

  • 您不应该在生产中使用
    fs.readFileSync
    。任何同步功能都将阻止事件循环,直到执行完成,从而延迟所有后续操作(如有必要,请谨慎使用)。几天前,我自己经历了最糟糕的经历,并以一种艰难的方式学会了这一点

    在express中,您可以使用
    param
    query
    定义路由,并使用该路由映射
    fs.readFile
    回调函数中的内容

    ...
    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"]
    ...
    
    /** 
    * 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
    非常重要,否则您可能会收到错误:发送后无法设置标题

    免责声明上述代码不适用