在Express Application中从JS文件追加JSON文件

时间:2018-11-06 03:59:46

标签: node.js json express

这是一次学习上的挣扎,我可能只是从一个尴尬的角度来解决这个问题,但我们的指导值得赞赏。该项目仅使用HTML,Node和Express。

我有一个小应用程序,该应用程序应进行调查输入以建立“朋友”个人资料(基本上只有一个名称,imgURL和7个问题,每个问题的答案为1-5)。我想将所有具有这些属性的Friend对象保存在data子目录中的JSON文件中,以便在添加新用户时,我可以将这些对象相互比较。

在前端,我希望一次通过一个引导卡来完成每个阶段,所以我有一个questions.js文件,该文件操纵DOM以名称和imgURL开头,并创建一个新的“ Friend”对象,然后一次执行一个问题(从字符串数组中打印问题文本)并捕获单选按钮选择(值1-5)on("submit")。最终结果是我遍历了所有问题,获取了提交的值,并将它们推到friend对象内的“分数”数组中,从而得出:

{
    "name": "Ahmed",
    "photo": "https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/6/005/064/1bd/3435aa3.jpg",
    "scores": [5, 1, 4, 4, 5, 1, 2, 5, 4, 1]
  }

所有这些都能很好地工作,最终我可以很好地引导用户浏览问题和新的Friend对象,并将所有需要的数据保留在链接的JS文件中。

现在我该如何在friends.json文件中将新的Friend对象作为数组项推送?我有点明白,我可能需要在questions.js内进行Ajax调用,或者我不在基地内,这属于我的app.post中的server.js路由之内,但到目前为止研究和试验只会带来更多的混乱。

这可能是一个很棘手的问题,但是我认为我需要学习一种最佳实践。非常感谢任何见识!

1 个答案:

答案 0 :(得分:2)

使用Fetch API进行POST请求

如前所述,您需要在服务器中使用POST路由来处理该问题。

您的前端应使用该新创建的对象对该端点进行AJAX POST调用。您可以使用Featch API来做到这一点:

fetch('http://localhost:8080/api/friends', {
    method: "POST",
    headers: {
        "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify({
        name: "Ahmed",
        photo: "https://media.licdn.com/.../foo.jpg",
        scores: [5, 1, 4, 4, 5, 1, 2, 5, 4, 1],
    }),
});

修改后端的数据

然后,假设这只是一个简单的学习示例,在您的后端,您有两个选择:

  • 已将friends.json文件作为数组加载到内存中,然后向其中推送一个新元素。
  • 在每个请求上加载,解析并保存friends.json

如果这将是生产服务器,那么您可以考虑使用REDIS,MongoDB或任何其他满足您需求的数据库。

在这里您可以同时看到它们:

// This will be loaded and parsed already (only used in option 1):
const friends = require("../data/friends.json");

// Only used in option 2:
const fs = require('fs');

// Tell the server to parse JSON bodies in your requests:
const bodyParser = require("body-parser");
app.use(bodyParser.json()); // Support JSON-encoded bodies.

// Get existing friends:
app.post('/api/friends', function(req, res, next) {
    // Option 1, persisted in memory:
    res.json(friends);

    // Option 2, loaded and saved everytime:
    try {
        res.json(JSON.parse(fs.readFileSync("../data/friends.json")));
    } catch(err) {
        // JSON.parse might fail:
        next(err);
    }
});

// Create new friend:
app.post('/api/friends', function(req, res, next) {
    // Option 1, persisted in memory:
    friends.push(req.body); // This should be validated properly!
    res.json(friends);

    // Option 2, loaded and saved everytime:
    try {
        const friends = JSON.parse(fs.readFileSync("../data/friends.json"));
        friends.push(req.body); // This should be validated properly!
        fs.writeFileSync("../data/friends.json", JSON.stringify(friends));
        res.json(friends);
    } catch(err) {
        // JSON.parse or fs.writeFileSync might fail:
        next(err);
    }
});

✨推荐使用人体分析器的方法

作为附加建议,即使您会在许多资源中看到body-parser被用作app.use(bodyParser.json())the recommended way to use it还是仅将其添加到与其相关的路由中用于:

  

特快路线

     

此示例演示了将主体解析器专门添加到需要它们的路由。通常,这是与Express结合使用body-parser的最推荐方法。

因此,您可以这样做:

const bodyParser = require("body-parser");
const jsonParser = bodyParser.json();

...

app.post('/api/friends', jsonParser, function(req, res, next) { ... }