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
相关产品推荐
相关产品推荐

