第四章 前后端数据交换格式详解

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 第四章 前后端数据交换格式详解

1. JSON数据结构与序列化/反序列化

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,基于JavaScript的一个子集,易于人阅读和编写,同时也易于机器解析和生成。在前后端通信中,JSON格式被广泛用于传递结构化的数据。

1.1 JSON数据结构

JSON由键值对组成,可以嵌套形成复杂的数据结构,包括对象(在JSON中表示为花括号 {} 包围的键值对集合)和数组(方括号 [] 包围的值列表)。例如:

{
  "user": {
    "name": "John Doe",
    "age": 30,
    "email": "john.doe@example.com"
  },
  "items": [
    {"id": 1, "name": "Item 1"},
    {"id": 2, "name": "Item 2"}
  ]
}

1.2 JSON序列化

序列化是指将JavaScript对象或数据结构转换成JSON字符串的过程,通常通过JSON.stringify()方法实现。如:

let user = {
  name: "John Doe",
  age: 30,
  email: "john.doe@example.com"
};

// 序列化为JSON字符串
let jsonString = JSON.stringify(user);
console.log(jsonString); // '{"name": "John Doe", "age": 30, "email": "john.doe@example.com"}'

1.3 JSON反序列化

反序列化则是将JSON字符串还原成JavaScript对象的过程,使用JSON.parse()方法完成。例如:

let jsonString = '{"name": "John Doe", "age": 30, "email": "john.doe@example.com"}';

// 反序列化为JavaScript对象
let userObject = JSON.parse(jsonString);
console.log(userObject.name); // 'John Doe'

1.4 JSON.stringify()详解

JSON.stringify() 是 JavaScript 中用于将一个JavaScript值(对象或者数组)转换为一个JSON字符串的方法。这个方法在实际开发中解决的主要问题包括:

  1. 数据序列化:当你需要将JavaScript对象或数组发送给服务器,例如通过AJAX请求时,你需要将这些复杂的数据结构转换成可以传输的文本格式,也就是JSON格式。
let user = {
  name: "John Doe",
  age: 30,
  address: {
    city: "New York",
    country: "USA"
  }
};

// 序列化为JSON字符串
let jsonString = JSON.stringify(user);
// 发送给服务器...
  1. 本地存储:浏览器提供的localStorage和sessionStorage只能存储字符串类型的数据。如果你想要持久化保存复杂的对象数据,就需要先使用JSON.stringify()将其转化为字符串形式再进行存储。
localStorage.setItem('user', JSON.stringify(user));
// 后续从本地存储恢复对象
const storedUser = JSON.parse(localStorage.getItem('user'));
  1. 跨域通信:在Web Workers、Service Workers或iframe间进行跨上下文通信时,JSON是常用的数据交换格式,因此会用到JSON.stringify()
  2. 日志记录:在调试过程中,为了方便查看和理解复杂对象的内容,开发者可能会选择将对象转化为可读性更好的JSON字符串打印出来。
  3. 深拷贝:虽然这不是JSON.stringify()设计的主要目的,但有时候它可以被用来创建JavaScript对象的浅复制(如果属性值不包含函数或循环引用),通过转换成字符串后再解析回新的对象实现。
let copyOfUser = JSON.parse(JSON.stringify(user));

JSON.stringify()的详细用法还包括几个可选参数来定制序列化过程:

  • replacer: 可以是一个函数或数组,用于控制哪些属性会被序列化以及它们如何被序列化。函数作为属性名和属性值的遍历器,决定返回什么值;数组则指定只序列化指定的属性名。
let customUser = JSON.stringify(user, (key, value) => {
  if (typeof value === 'string') return '***'; // 替换所有字符串为星号
  return value; // 其他值保持不变
});
  • space: 指定缩进用的空白字符串数量,用于美化输出的JSON字符串(便于阅读)。若为空,则无任何空格;若为数字,则代表每个级别缩进的空格数;也可以是一个字符串(如\t代表制表符缩进)。
let prettyJson = JSON.stringify(user, null, 2); // 输出格式化的JSON,每级缩进2个空格
console.log(prettyJson);

cycle detection:默认情况下,如果对象之间存在循环引用,JSON.stringify()会抛出错误。不过,在一些较新版本的JavaScript环境中,引入了对循环引用检测的支持,允许安全地处理此类情况。但在大多数通用场景下,开发人员仍需确保避免递归引用以确保成功序列化。

1.5 JSON.stringify()方法无法直接处理循环引用的问题

在JavaScript中,JSON.stringify()方法无法直接处理循环引用的问题,即当对象之间存在相互引用时(一个对象的属性引用了另一个对象,而后者又反过来引用了前者),尝试将这样的对象转换为JSON字符串时会抛出TypeError错误。

例如:

let obj1 = {};
let obj2 = { ref: null };
obj1.ref = obj2;
obj2.ref = obj1;

JSON.stringify(obj1); // 抛出 TypeError: Converting circular structure to JSON

解决循环引用问题的方法通常需要手动干预或借助第三方库来实现。以下是一个手动处理循环引用的简要示例:

function stringifyWithCycleSupport(obj, cache = []) {
  if (typeof obj !== 'object' || obj === null) {
    return JSON.stringify(obj);
  }

  // 检查缓存中是否已包含该对象
  const cachedIndex = cache.indexOf(obj);
  if (cachedIndex !== -1) {
    // 如果已包含,则返回表示循环引用的占位符
    return '"__cycle__" + (' + cachedIndex + ')';
  }

  // 将当前对象添加到缓存中
  cache.push(obj);

  let stringifiedObj;
  if (Array.isArray(obj)) {
    stringifiedObj = `[${obj.map((value) => stringifyWithCycleSupport(value, cache)).join(',')}]`;
  } else {
    stringifiedObj = `{${Object.keys(obj).map((key) => `"${key}": ${stringifyWithCycleSupport(obj[key], cache)}`).join(',')}}`;
  }

  return stringifiedObj;
}

// 使用自定义函数处理循环引用
const jsonStr = stringifyWithCycleSupport(obj1);

另一种方式是使用如flattedjson-stringify-safe等第三方库,这些库已经实现了自动检测和处理循环引用的功能,使得能够安全地序列化具有循环引用的对象。例如,在使用flatted库的情况下:

import * as flatted from 'flatted';

let jsonStr = flatted.stringify(obj1);

请注意,尽管通过上述方式可以生成不含循环引用的JSON字符串,但是还原后的对象结构不再保持原有的引用关系,而是以特定格式记录循环引用的情况。在实际应用中,这种处理方式只适用于需要将循环引用的数据持久化存储或传输给其他服务端程序,而不是为了在JavaScript环境中保持原始的对象结构进行深拷贝操作。

2. XML与JSON在HTTP通信中的优劣比较

2.1 XML (eXtensible Markup Language)

  • 优点
  • 易于扩展,支持自定义标签,适合高度结构化、严格规范的数据传输。
  • 支持注释、文档类型声明以及命名空间等特性,更适用于需要丰富元信息和良好文档性的场景。
  • 跨语言、跨平台兼容性好,有众多成熟的工具和库支持处理。
  • 缺点
  • 相对于JSON,XML语法冗长且占用更多的存储空间。
  • 解析复杂度较高,特别是涉及到复杂的XPath查询时。
  • 不是专门为Web服务而设计,不适合直接与JavaScript进行交互。

2.2 JSON

  • 优点
  • 语法简洁,与JavaScript紧密集成,可以直接转换为原生对象,便于前端快速处理。
  • 数据体积较小,加载速度快,利于提高网络性能。
  • 更加适应现代Web开发需求,已成为主流的Web服务数据交换格式。
  • 缺点
  • 对于非结构化或者需要丰富元信息的数据描述能力较弱。
  • 非常严格的语法要求,如缺少引号、额外的逗号等可能导致解析错误。

3. 数据绑定与模板引擎在前后端交互中的作用

在现代Web应用中,数据绑定和模板引擎大大简化了前后端交互过程,使得动态内容渲染更加高效便捷。

  • 数据绑定

数据绑定是一种自动同步模型数据和视图的技术,当模型数据发生变化时,视图会自动更新;反之,用户对视图的修改也会反映到模型数据上。比如在Vue.js、Angular和React等框架中,都实现了强大的双向数据绑定机制,让开发者无需手动操作DOM,即可实现界面与后台数据的无缝连接。

模板引擎

模板引擎则负责根据接收到的JSON数据填充预定义的HTML模板,并生成最终展现给用户的页面。模板引擎可以根据后端传来的JSON数据动态生成HTML内容,减少服务器端生成HTML页面的压力,同时提升前端渲染速度和用户体验。例如Jinja2、Handlebars、Mustache等都是常用的模板引擎,它们允许你使用特殊的语法(占位符、逻辑控制语句等)在HTML中插入动态数据。


结合以上技术,前后端能够以更高效的方式进行数据交换和展示,极大地提高了Web应用的开发效率和运行性能。

相关文章
|
6月前
|
缓存 监控 安全
中间件数据交换的功能介绍
中间件数据交换在数据传输、采集、应用管理、调度缓存、监控报警、映射规则及异步解耦等方面发挥关键作用。它确保数据安全、高效、可靠交换,支持系统稳定和灵活适应业务需求。
93 2
|
数据采集 监控 安全
数据标准应用(三):数据标准落标监控-下篇
数据标准创建完成后,需要指定其关联的资产对象才能发挥应用价值。数据标准和资产对象的映射关系通过落标映射规则来管理,对象是否遵循了映射到的标准定义则通过落标监控规则来判断。本文为您介绍落标监控评估的基本概念和监控逻辑。Dataphin 支持通过定义标准属性和资产对象元数据字段之间的匹配关系,自动生成数据标准和资产对象的映射关联;针对已确定的映射关系,可结合数据标准的定义对关联的资产对象进行落标监控,包括元数据监控和内容质量监控。上篇,我们为大家介绍了数据标准监控的分类和配置方式,本期我们将为您介绍配置好的落标监控如何生效以及如何查看监控结果。
536 0
|
6月前
|
XML JSON 中间件
中间件数据格式的转换
中间件数据格式转换涉及在系统间传递数据时调整格式,以适应不同标准。常见转换包括:JSON与XML互转、文本到二进制、结构化与非结构化数据转换、不同数据标准间的转换及处理自定义格式。实现转换通常借助编程语言(如Python的json、xml库)和工具(如Apache NiFi、StreamSets)。设计时需考虑数据源、目标、传输和性能需求。
83 2
|
6月前
|
负载均衡 监控 安全
中间件功能之数据交换
中间件在数据交换中起关键作用,负责数据的可靠、高效和安全传输。其主要功能包括:数据格式转换、数据路由、数据同步、数据过滤与验证、负载均衡、安全控制及日志记录与监控。通过这些功能,中间件确保了不同系统间数据的无缝对接、一致性、质量和安全性,提升了数据交换的效率。
97 4
|
6月前
|
前端开发
java实现PBOC的TLV格式解析,超简单的解析(全互联网最简单)
java实现PBOC的TLV格式解析,超简单的解析(全互联网最简单)
|
JSON 前端开发 数据格式
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
131 0
crontab、JSON、前端、后端、通信、转换、编码、解码、表达式工具
|
存储 机器学习/深度学习 缓存
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
二十七、网络层概述和数据交换方式
|
传感器 编译器 Python
Python编程基础:实验7——文件和数据格式化
巩固Python文件操作相关基础知识,熟练的掌握文件操作至关重要。
450 0
Python编程基础:实验7——文件和数据格式化
|
机器学习/深度学习 算法 JavaScript
一文彻底解析数据库设计思路
一文彻底解析数据库设计思路
242 0
一文彻底解析数据库设计思路