首页 > 解决方案 > 在 Express 应用程序中从 JS 文件附加 JSON 文件

问题描述

这是一场学习斗争,我可能只是从一个尴尬的角度来处理这个问题,但我们很感激指导。该项目仅使用 HTML、Node 和 Express。

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

在我的前端,我想一次通过每个阶段一张引导卡,所以我有一个questions.js文件可以操纵 DOM 以名称和 imgURL 开头并创建一个新的“朋友”对象,然后在一个问题时间(从字符串数组打印问题文本)并捕获单选按钮选择(值 1-5)on("submit")。最终结果是我遍历了所有问题,抓取了提交的值,并将它们推送到朋友对象中的“分数”数组,结果如下:

{
    "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 文件中。

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

这可能是一个古怪的问题,但我认为那里有一个我需要学习的最佳实践。非常感谢任何见解!

标签: node.jsjsonexpress

解决方案


使用 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 的方法

作为一个额外的建议,即使你会看到在很多资源中body-parser被使用,推荐的使用方法是只将它添加到它相关的路由中:app.use(bodyParser.json())

特快专线

此示例演示了将正文解析器专门添加到需要它们的路由中。一般来说,这是将 body-parser 与 Express 一起使用的最推荐方式。

所以,在你的情况下,你会这样做:

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

...

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

推荐阅读