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

TypeScript中如何将含JSON文件的FormData正确解析为JSON对象

故障原因
  • 核心问题是你全程用字符串模板+replace替换占位符的方式拼接JSON结构:Gcode文件仅包含普通文本、换行、回车符,你之前只手动转义了\r和\n所以能正常运行;但JSON文件本身自带大量双引号、反斜杠、制表符等JSON语法特殊字符,直接替换进字符串模板时,这些字符会直接破坏外层JSON的语法结构,执行JSON.parse时必然抛出解析错误。
  • 附带的逻辑缺陷:
    • 小文件传输分支里的formData3、formData4使用单引号包裹键和值,不符合标准JSON语法,即使内容没问题也会解析失败
    • 大文件分片直接按固定长度切割字符串,很容易把转义字符、多字节UTF-8字符从中间切断,导致分片后的内容非法
    • 大文件分支的完成通知模板里没有replaceFilename占位符,对应的replace操作完全无效
    • 你对读取到的文件内容额外执行了一次JSON.stringify,但后续是用字符串替换插入内容,转义逻辑不闭环,双引号等特殊字符依然会漏处理
修复方法

核心原则:绝对不要用字符串拼接、占位符替换的方式手动生成JSON,直接构造原生JavaScript/TypeScript对象,将动态内容直接赋值给对应字段,最后交给内置的JSON.stringify或者HTTP客户端自动做序列化,所有特殊字符的转义会由JS引擎自动完成,从根源上避免语法破坏问题。

修复后的完整sendFileToServer实现如下:

sendFileToServer(ns: number, i: number, value) {
  const deviceID = this.deviceID;
  const message = this.message;
  const http = this.http;
  const url = this.url;
  const options = this.options;

  const file = value.target.files[0];
  const filename = file.name;
  const isJsonFile = filename.endsWith('.json');
  const CHUNK_SIZE = 25000;

  // 发送文件名通知,直接构造对象,无需字符串拼接
  const nameNotifyPayload = {
    deviceId: deviceID,
    c8y_ua_command_WriteValue: {
      values: {
        [`ns=${ns};i=${i + 1}`]: {
          value: filename
        }
      }
    },
    description: isJsonFile ? "Send json filename to OPC UA server" : "Send gcode filename to OPC UA server"
  };
  http.post(url, nameNotifyPayload, options).subscribe(res => console.log(res));

  const fileReader = new FileReader();
  fileReader.onload = function () {
    const rawContent = fileReader.result as string;
    let offset = 0;
    let chunkIndex = 0;

    // 统一分片发送逻辑,大小文件兼容,减少重复代码
    const sendNextChunk = () => {
      if (offset >= rawContent.length) {
        // 所有分片发送完成,发送结束通知
        const finishPayload = {
          deviceId: deviceID,
          c8y_ua_command_WriteValue: {
            values: {
              [`ns=${ns};i=${i}`]: {
                value: isJsonFile ? "Json1" : "Gcode"
              },
              [`ns=${ns};i=${i + 1}`]: {
                value: filename
              }
            }
          },
          description: isJsonFile ? "Finished sending json file" : "Finished sending gcode"
        };
        setTimeout(() => http.post(url, finishPayload, options).subscribe(res => console.log(res)), 2000);
        alert(message);
        return;
      }

      // 切割当前分片,直接构造请求体,特殊字符自动转义
      const chunk = rawContent.slice(offset, offset + CHUNK_SIZE);
      const chunkPayload = {
        deviceId: deviceID,
        c8y_ua_command_WriteValue: {
          values: {
            [`ns=${ns};i=${i}`]: {
              value: chunk
            }
          }
        },
        description: "Send file chunk to OPC server"
      };

      setTimeout(() => {
        http.post(url, chunkPayload, options).subscribe(res => {
          console.log(res);
          offset += CHUNK_SIZE;
          chunkIndex++;
          sendNextChunk();
        });
      }, chunkIndex * 2000);
    };

    sendNextChunk();
  };
  fileReader.readAsText(file);
}
修复说明
  • 所有请求体不再使用字符串模板拼接,全部直接构造TS对象,动态节点ID用计算属性写法生成,字段值直接赋值,彻底避免特殊字符转义问题
  • 合并了大、小文件的重复逻辑,统一走分片发送流程,代码冗余量减少70%以上
  • 移除了手动替换\r/\n的逻辑,对象序列化时会自动处理所有需要转义的字符
  • 增加了文件类型自动识别,发送JSON文件时对应的描述、完成标记会自动适配,不会再硬编码写入Gcode相关的内容
  • 修正了之前分片长度和文件实际长度不匹配、无效replace、单引号语法错误等附带bug

内容的提问来源于stack exchange,提问作者Yuxuan L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 10:06:20