写入JSON文件(使用Node.js在本地主机服务器上工作)

3

我正在使用C3.js,这是一个基于广泛使用的D3.js可视化库构建的图表库。因此,在我创建的网页中,作为图表的一部分,我想包括用户交互,使用户可以通过在html页面上的表单输入值来创建一个新对象,并将其与已经绘制的当前对象一起绘制。我正在使用JSON数据作为读入图表的文件格式。我想知道如何从javascript代码中写入/更新该文件,以便数据现在包括新对象。由于我是一个网络技术方面的初学者,对于数据如何在服务器上更新并不是很确定。服务器是由app.js创建的本地主机,它创建了一个节点服务器。

var express = require('express');
var http = require('http');
var app = express();


app.use(express.static(__dirname + '/public'));

server = http.createServer(app);
server.listen('14000');

如果需要参考,我在app.js中包含了上述代码。JSON文件的格式如下所示...

[
      {name: "Lane Warner",age: 27,height: 231,weight: 120},
      {name: "Hickman Bishop",age: 29,height: 125,weight: 180},
      {name: "Tracy Sheppard",age: 30,height: 200,weight: 155},
      {name: "Madeleine Spence",age: 30,height: 179,weight: 112},
      {name: "Alicia Beasley",age: 36,height: 300,weight: 200},
      {name: "Bryant Fitzpatrick",age: 23,height: 321,weight: 250},
      {name: "Stevenson Mcdonald",age: 30,height: 155,weight: 199},
      {name: "Hannah Ratliff",age: 21,height: 189,weight: 136},
      {name: "Alexandra Williamson",age: 39,height: 258,weight: 123}
]
1个回答

1
你可以使用fs.readFile模块来读取文件,使用JSON.parse来解析JSON。

json-util.js:

var fs = require('fs');

module.exports.loadJson = function (file, callback) {
  fs.readFile('file.json', { encoding: 'utf8' }, function (err, data) {
    if (err) return callback(err); // file reading error
    try {
      // parse and return json to callback
      var json = JSON.parse(data);
      callback(null, json);
    } catch (ex) {
      // catch JSON parsing errors so your app doesn't crash
      callback(ex);
    }
  });
};

如果您想同步读取json文件,也可以使用json = require('file.json')。请注意,require()是相对于当前文件的,而fs.readFile()是相对于cwd的。
相反,您可以使用JSON.stringifyfs.writeFile重新编写JSON到文件中:
module.exports.writeJson = function (file, json, callback) {
  fs.writeFile(file, JSON.stringify(json), callback);
};

请注意并发问题,例如两个请求同时尝试修改同一个文件。类似这样的时间表将是不好的:
  1. 请求A读取JSON。
  2. 请求B读取JSON。
  3. 请求A向数组添加一项并重新编写JSON。
  4. 请求B向数组添加一项并重新编写JSON。
在这种情况下,请求A进行的添加操作将被请求B完全抹去。为了避免这种情况发生,最好始终只在内存中保存一份JSON副本,并在每次修改时重新编写它。我认为这超出了您的问题范围,但想要指出。
如果您不关心并发性,可以创建这样的应用程序:

app.js:

var express = require('express');
var http = require('http');
var app = express();

// if you're using Express 4.x, bodyParser is no longer built-in
var bodyParser = require('body-parser');

// here we import the file which has our loadJson and writeJson functions
var jsonUtil = require('./json-util.js');

app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());

app.post('/additem/:id', function (req, res, next) {
  // turn ID into a file name, and be careful not to expose security holes
  var filename = idToFileName(req.params.id);
  jsonUtil.loadJson(filename, function (err, json) {

    // TODO: make sure you handle errors
    // if err is not null, you can either consider it an error, or
    // you could simply say json = [] and start a new file

    // should also do validation checks like if(json instanceof Array) and
    // verify that req.body exists and is properly formatted, etc

    json.push(req.body); // push the object from the request body into the array

    // re-save the file
    jsonUtil.writeJson(filename, json, function (err) {
      if (err) next(err);
      else res.send(200);
    });
  });
});

server = http.createServer(app);
server.listen('14000');

然后,一个类似于以下内容的请求:
POST /additem/1
Content-Type: application/json

{ "name": "Alexandra Williamson", "age": 39, "height": 258, "weight": 123 }

将追加到与json文件id = 1映射的数组中。

所以我理解你在app.js代码中做了什么以及使用模块的方式。你在响应底部放置的请求是我有疑问的地方。那个请求能否放在HTML脚本部分? - user3775273
@user3775273,这只是一个向/additem/1发送HTTP POST请求的操作,需要设置Content-Type头为application/json,并且请求体是JSON格式的数据。最简单的方式可能是通过ajax请求发送。 - Bret Copeland
我对与web相关的技术是新手,但我使用node的原因不是因为我不想使用ajax请求吗?我有一个本地json文件路径数组,我只想添加到当前的文件。我需要知道如何让我制作的表单数据被服务器所看到,并附加到json文件的数组末尾。然而,我完全不知道该怎么做。我阅读了关于使用表单的action和method属性的内容。您能提供一些反馈吗?感谢您迄今为止的帮助。 - user3775273
Node.js只是一种后端语言,与使用ajax的决定无关。如果您的问题是关于如何使用node.js解析通过表单发送的数据,那么这是一个单独的问题。有很多信息可以参考,例如,您可以从body-parser中间件或者谷歌搜索开始。如果您仍然迷失方向,可以在Stack Overflow上提出另一个问题。 - Bret Copeland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接