以前端角度来看序列化

1. what? why?

  • 序列化:将数据结构或对象状态 转换成一个可以存储或传输的格式 的过程

    • 意味着可以将复杂的数据结构转换成简单的字节流或字符串,以便于存储或传输
  • 反序列化:将这些数据恢复成原始形式的过程,是序列化的逆过程

  • 从序列化本质来看,主要是 存储 和 传输

传输方面:不同程序通信会发送各种各样的资源(文本、图片、音频等),但网络传输是通过二进制序列的形式传输的,因此需要将原有数据序列化,再在接收端恢复

存储方面:不同机器、执行环境,可能有不同的数据处理方式,可能会导致反序列化出现问题,因此也需要序列化

常见使用场景:

  • 数据持久化,保存到数据库(二进制)
  • 数据从数据库里读出 来到java等后端语言(反序列化)
  • 数据从后端 ------> 前端(JSON)
  • 数据从JSON变成JS对象(JSON.stringify、JSON.parse)

2. how?

JSON.stringify & JSON.parse

在js中提到对象转JSON字符串,基本上都会想到JSON.stringify方法,以及对应的解析方法JSON.parse

以JSON.stringify为例,前端日常可能会用到的场景:

  • 数据传输:
    • 服务端返回JSON string,需要用JSON.parse进行解析
    • 客户端在POST时要将JSON用JSON.stringify转成string
  • localStorage存储数据时要转string,数据需要序列化
  • 可能会用JSON.stringify和JSON.parse做对象深拷贝

但JSON.stringify序列化会存在以下问题:

  • 转换的数据中,包含function、undefined、symbol值,以及不可枚举属性,序列化后会消失
  • 包含NaN、Infinity值(含-Infinity)、null,序列化后结果是null
  • 包含Date对象,会变成字符串
  • 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,只会序列化可枚举的属性
  • 包含RegExp,会变成空对象
  • 循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误

实现axios序列化

axios序列化整个流程:

rust 复制代码
    section 发送请求
        发起网络请求 -> 序列化请求数据 -> 发送请求

    section 接收响应
        接收响应数据 -> 反序列化响应数据 -> 处理响应数据

Content-type对应不同格式的请求数据,前端在POST请求时需要根据后端接口的要求选择合适的类型,并正确设置请求头,常见的类型:

  • application/json:用于发送JSON格式的数据,请求体是JSON对象 或 数组
  • application/x-ww-form-urlencoder:用于发送URL编码的表单数据,请求体是以键值对的形式发送,键值对之间以&隔开
  • application/xml:用于发送XML格式的数据,请求体是一个XML文档
  • multipart/form-data:用于发送二进制数据,通常用于上传文件。请求体的格式是多部分的,每个部分可以是一个文本字段或一个文件

默认情况下,axios会将请求数据自动转换成JSON格式 发送,后台对应的接口正好是处理Content-Type=application/json类型的入参,此时不需要处理数据。

但有的时候后台是按照application/x-ww-form-urlencoder 方式在接口中进行数据获取和处理的,我们post正常传参后台是收不到的,这时我们必须对参数数据进行序列化处理,以表单形式(键值对)发送给后台

axios提供了两种序列化参数的方式,着重掌握qs:

  • 使用URLSearchParams对象:在浏览器中使用,它能够自动处理URL参数的编码问题
  • 使用qs库:qs库是一个解析和字符串化URL查询字符串的库

qs

qs是一个用于处理URL查询字符串的库,可以用来处理复杂的请求参数,如嵌套对象、数组等。一般当需要发送含复杂数据结构的POST请求时,就可以用qs将JS对象序列化成URL查询字符串

qs.stringify:将 对象 序列化成URL 的形式,以&进行拼接。它跟JSON.stringify有所不同:

css 复制代码
var a = {name:'kk',age:10};
qs.stringify(a)
// 'name=kk&age=10'
JSON.stringify(a)
// '{"name":"kk","age":10}'

qs.parse:将URL解析成对象的形式

在post请求后端数据使用qs序列化:

php 复制代码
npm install qs
// user.js
import qs from 'qs';
export function loginAPI(paramsList) {
  return myAxios({
    url: '/api/login',
    method: 'post',
    data: paramsList,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    transformRequest: [
      (data) => {
        return qs.stringify(data)
      }
    ],
  });
}
ini 复制代码
const axios = require('axios');
const qs = require('qs');
const data = {
  user: {
    name: 'John',
    age: 30
  },
  interests: ['coding', 'reading']
};
axios.post('/api/user', qs.stringify(data))
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error:', error);
  });
相关推荐
m0_7482361115 分钟前
Calcite Web 项目常见问题解决方案
开发语言·前端·rust
Watermelo61728 分钟前
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
开发语言·前端·javascript·算法·数据挖掘·数据分析·ecmascript
m0_7482489429 分钟前
HTML5系列(11)-- Web 无障碍开发指南
前端·html·html5
m0_7482356141 分钟前
从零开始学前端之HTML(三)
前端·html
一个处女座的程序猿O(∩_∩)O3 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink6 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者7 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-8 小时前
验证码机制
前端·后端
燃先生._.9 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js