You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript+HTML如何将字符串字面量写入JSON文件?

问题解决:浏览器端无法使用Node.js的fs模块 + 正确生成并保存JSON数据

核心错误原因

你看到的require is not defined错误,是因为浏览器环境不支持Node.js专属的fs文件系统模块。require是Node.js的模块加载语法,浏览器没有这个API,而且出于安全限制,前端JavaScript也不能直接读写本地文件,必须通过后端服务中转。

两步解决问题

1. 放弃手动拼接JSON,改用JSON.stringify生成合法JSON

手动拼接字符串很容易因为用户输入的特殊字符(比如双引号、换行符)破坏JSON结构,正确的做法是先构建JavaScript对象,再用JSON.stringify转换为标准JSON字符串:

function writeToRecipeFile() {
    // 1. 构建Recipe数据对象
    const recipe = {
        image: "",
        title: document.getElementById("titleInput").value,
        description: document.getElementById("descriptionInput").innerText,
        ingredients: [],
        steps: [],
        // 修正原代码中的拼写错误:getElemenyById → getElementById
        info: [
            parseInt(document.getElementById("prep-time-hr").value) || 0,
            parseInt(document.getElementById("prep-time-min").value) || 0,
            parseInt(document.getElementById("servings").value) || 0,
            parseInt(document.getElementById("serving-size").value) || 0,
            document.getElementById("prep-time-hr").value // 此处疑似重复,建议检查业务逻辑
        ]
    };

    // 收集食材数据
    for (let i = 1; i <= ingredientCount; i++) {
        recipe.ingredients.push([
            document.getElementById(`ingredientType${i}`).value,
            parseFloat(document.getElementById(`ingredientAmount${i}`).value) || 0,
            document.getElementById(`ingredientMeasurement${i}`).value
        ]);
    }

    // 收集步骤数据
    for (let i = 1; i < stepCount; i++) {
        recipe.steps.push(document.getElementById(`stepInput${i}`).innerText);
    }

    // 2. 转换为格式化的JSON字符串
    const recipeJson = JSON.stringify(recipe, null, 4);

    // 3. 发送到后端保存(关键:浏览器无法直接写本地文件)
    saveRecipeToServer(recipeJson);
}

2. 搭建后端接口处理文件写入

用Node.js + Express写一个简单的后端接口,接收前端发送的JSON数据并写入文件:

后端代码(Node.js + Express)

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

// 解析前端发送的JSON请求体
app.use(express.json());

// 处理保存食谱的接口
app.post('/save-recipe', (req, res) => {
    const { recipeData, filePath } = req.body;
    // 安全处理文件路径,避免路径遍历攻击
    const targetPath = path.resolve(__dirname, filePath);

    fs.writeFile(targetPath, recipeData, (err) => {
        if (err) {
            console.error('保存失败:', err);
            return res.status(500).json({ success: false, msg: '文件保存失败' });
        }
        res.json({ success: true, msg: '文件保存成功' });
    });
});

// 启动服务器
app.listen(3000, () => {
    console.log('后端服务运行在 http://localhost:3000');
});

前端发送请求的函数

function saveRecipeToServer(recipeJson) {
    fetch('http://localhost:3000/save-recipe', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            recipeData: recipeJson,
            filePath: "/JS_Scripts/Recipes/JSON/test.json"
        })
    })
    .then(res => res.json())
    .then(result => {
        alert(result.msg);
    })
    .catch(err => {
        console.error('请求失败:', err);
    });
}

特殊场景说明

如果你的项目是Electron桌面应用(而非纯网页),可以直接在主进程中使用fs模块,通过IPC和渲染进程通信来处理文件写入,但仍然不建议在渲染进程中直接调用Node.js模块。

内容的提问来源于stack exchange,提问作者Zachary Lund

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 11:37:06