JavaScript 实战:如何操作本地 JSON 文件实现简易数据存储与“添加”功能**
在 Web 开发中,我们经常需要处理数据,对于小型项目、原型开发或者本地测试而言,配置一个完整的数据库(如 MySQL、MongoDB)可能显得过于笨重,使用轻量级的 JSON 文件作为本地数据存储介质,是一个非常便捷的选择,本文将详细探讨如何使用 JavaScript(主要在浏览器端和 Node.js 环境下)来操作本地的 JSON 文件,实现类似“数据库”的添加数据功能。
核心概念:理解 JSON 文件的特性与限制
我们需要明确一点:JSON 文件本质上是一个文本文件,它本身不是一个真正的数据库,数据库通常具备事务、索引、并发控制等复杂特性,而 JSON 文件是静态的,直接“在文件中添加数据”对于浏览器端的 JavaScript 由于安全限制(同源策略、文件系统访问限制),几乎是不可能直接修改用户机器上的任意文件的。
我们可以通过一些变通的方法来模拟这种“添加”行为,核心思路是:
- 读取:将 JSON 文件的内容读取到内存中(通常是 JavaScript 对象或数组)。
- 修改:在内存中的 JavaScript 数据结构上进行添加、删除、更新等操作。
- 写入:将修改后的 JavaScript 数据结构转换回 JSON 字符串,并覆盖原来的 JSON 文件(或者写入一个新的 JSON 文件)。
这里的“添加”操作,主要指的是向内存中的 JavaScript 数组或对象添加新的数据项,然后整体替换文件内容。
浏览器端 JavaScript (HTML + JS)
在浏览器端,我们不能直接读写用户本地文件系统中的任意文件,但可以通过用户交互(如文件输入 <input type="file">)让用户选择文件,或者通过 JavaScript 动态创建和下载文件来实现。
示例:通过用户选择文件,添加数据后允许用户下载新文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">JSON 文件数据添加示例</title>
</head>
<body>
<h1>本地 JSON 文件数据添加工具</h1>
<div>
<label for="jsonFile">选择 JSON 文件:</label>
<input type="file" id="jsonFile" accept=".json">
</div>
<div id="fileContent" style="margin-top: 20px;">
<!-- 文件内容将显示在这里 -->
</div>
<div id="addDataForm" style="margin-top: 20px; display: none;">
<h3>添加新数据</h3>
<input type="text" id="newName" placeholder="名称">
<input type="number" id="newAge" placeholder="年龄">
<button onclick="addData()">添加数据</button>
</div>
<div id="result" style="margin-top: 20px;"></div>
<script>
let jsonData = [];
let fileInput = document.getElementById('jsonFile');
let fileContentDiv = document.getElementById('fileContent');
let addDataFormDiv = document.getElementById('addDataForm');
let resultDiv = document.getElementById('result');
fileInput.addEventListener('change', function(event) {
let file = event.target.files[0];
if (file) {
let reader = new FileReader();
reader.onload = function(e) {
try {
jsonData = JSON.parse(e.target.result);
if (!Array.isArray(jsonData)) {
jsonData = [jsonData]; // 如果不是数组,转为数组方便添加
}
displayData();
addDataFormDiv.style.display = 'block';
resultDiv.innerHTML = '';
} catch (error) {
resultDiv.innerHTML = `<p style="color: red;">JSON 文件解析错误: ${error.message}</p>`;
}
};
reader.readAsText(file);
}
});
function displayData() {
fileContentDiv.innerHTML = '<pre>' + JSON.stringify(jsonData, null, 2) + '</pre>';
}
function addData() {
let name = document.getElementById('newName').value;
let age = parseInt(document.getElementById('newAge').value);
if (name && !isNaN(age)) {
let newData = {
id: Date.now(), // 简单生成唯一ID
name: name,
age: age,
createdAt: new Date().toISOString()
};
jsonData.push(newData);
displayData();
resultDiv.innerHTML = `<p style="color: green;">数据添加成功!</p>`;
// 清空输入框
document.getElementById('newName').value = '';
document.getElementById('newAge').value = '';
} else {
resultDiv.innerHTML = `<p style="color: red;">请填写完整的名称和年龄!</p>`;
}
}
// 提供下载功能
function downloadJson() {
let dataStr = JSON.stringify(jsonData, null, 2);
let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
let exportFileDefaultName = 'updated_data.json';
let linkElement = document.createElement('a');
linkElement.setAttribute('href', dataUri);
linkElement.setAttribute('download', exportFileDefaultName);
linkElement.click();
}
// 添加下载按钮
let downloadBtn = document.createElement('button');
downloadBtn.textContent = '下载更新后的 JSON 文件';
downloadBtn.onclick = downloadJson;
downloadBtn.style.marginTop = '10px';
resultDiv.appendChild(downloadBtn);
</script>
</body>
</html>
浏览器端实现逻辑解析:
- 文件选择与读取:使用
<input type="file">让用户选择 JSON 文件,通过FileReaderAPI 读取文件内容为文本,然后用JSON.parse()解析成 JavaScript 对象/数组。 - 数据展示:将解析后的数据以格式化的形式显示在页面上(使用
<pre>和JSON.stringify)。 - 添加数据:用户提供新数据后,将其构造成一个对象(通常包含唯一标识符,如时间戳
Date.now()),然后使用push()方法添加到内存中的jsonData数组。 - 更新显示:重新调用
displayData()展示更新后的数据。 - 下载新文件:由于浏览器端无法直接修改原文件,我们提供下载功能,使用
JSON.stringify()将更新后的数据转换回 JSON 字符串,创建一个 Blob 或 Data URI,然后通过动态创建<a>标签并触发点击下载,让用户保存新的 JSON 文件,用户需要手动用新文件替换旧文件。
Node.js 环境
在 Node.js 环境下,我们有更直接的方式来操作文件系统,可以使用内置的 fs (File System) 模块。
示例:使用 Node.js 读取、修改并写入 JSON 文件
假设我们有一个名为 data.json 的文件,内容如下:
[
{ "id": 1, "name": "Alice", "age": 30 },
{ "id": 2, "name": "Bob", "age": 25 }
]
我们想要向这个数组添加一个新的对象。
// 引入文件系统模块
const fs = require('fs');
const path = require('path');
// JSON 文件路径
const jsonFilePath = path.join(__dirname, 'data.json');
// 要添加的新数据
const newData = {
id: 3,
name: "Charlie",
age: 28,
createdAt: new Date().toISOString()
};
try {
// 1. 读取 JSON 文件
const fileData = fs.readFileSync(jsonFilePath, 'utf8');
// 2. 解析 JSON 数据为 JavaScript 对象
let jsonData = JSON.parse(fileData);
// 确保 jsonData 是一个数组
if (!Array.isArray(jsonData)) {
jsonData = [jsonData];
}
// 3. 添加新数据到数组
jsonData.push(newData);
// 4. 将更新后的 JavaScript 对象转换回 JSON 字符串
const updatedJsonString = JSON.stringify(jsonData, null, 2); // null, 2 用于格式化
// 5. 将 JSON 字符串写回文件(覆盖原文件)
fs.writeFileSync(jsonFilePath, updatedJsonString, 'utf8');
console.log('数据添加成功,文件已更新!');
console.log('更新后的数据:', jsonData);
} catch (error) {
console.error('操作 JSON 文件时发生错误:', error);
}
Node.js 实现逻辑解析:
- 引入模块:使用
require('fs')引入 Node.js 的文件系统模块。 - 文件路径:使用
path.join(__dirname, 'data.json')构建文件的绝对路径,确保文件能被正确找到。 - 读取文件:使用



还没有评论,来说两句吧...