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);
});