过滤请求参数中的空字符串,null和undefined值

6,670 阅读2分钟

背景

在开发表单过程,有的字段在某些场景下可能没有实际值,传递的还是初始值(比如空字符串'',空对象指针null和未定义值undefined),在我的项目中,会转换为JSON字符串后给到后端的同学,经常会遇到数据类型匹配不上的问题,双方的矛盾出现了233~

思路

基础版本

比如一个整型数据类型的表单字段,在前端初始化时是null,该字段是非必填项,用户没有输入,到后端就直接报错,提示这个用户类型有问题,那么在页面里,提交表单之前,进行字段进行摘除或者赋予一个初始值(类型为后端可接受的)。

// 移除该字段(项目使用的)
delete postForm.xxx

// 或者赋予一个初始值(类型为后端可接受的)
postForm.xxx = {}
postForm.xxx = 0

进阶版本

上面的解决方法在涉及数据转换的页面较少的情况下,暂时可以,但是如果页面比较多,每个页面都需要手动处理下,这时业务代码和数据转换杂糅在一块,会影响业务代码的可读性,所以不是很建议,最好在某一个地方统一进行过滤处理,我的项目中是使用axios库发送请求,所以可以在axios的请求拦截器中,对数据进行统一过滤

  • axios的请求数据 在我的项目中,请求的数据一般放在axios.config的params或者data中,所以在进行过滤时,仅过滤这两个字段中的数据,这里需要结合项目的实际情况进行处理

请求api一般如下

// post请求的参数放在data
export function createUser(data) {
  return request({
    url: `/user`,
    method: 'post',
    data
  })
}

// 多个参数的get请求,参数放在params
export function userList(params) {
  return request({
    url: `/user`,
    method: 'get',
    params
  })
}

实现

  • 过滤函数 过滤config.dataconfig.params两个属性里的参数
const _cloneDeep = require('lodash/cloneDeep')

// 移除空字符串,null, undefined
function clearEmptyParam(config) {
  ['data', 'params'].forEach(item => {
    if (config[item]) {
      const keys = Object.keys(config[item])
      if (keys.length) {
        keys.forEach(key => {
          const rawType = toRawType(config[item])
          if (['', undefined, null].includes(config[item][key]) &&
              ['Object'].includes(rawType)) {
            // 移除属性之前,进行深拷贝断开引用,避免影响页面
            config[item] = _cloneDeep(config[item])
            delete config[item][key]
          }
        })
      }
    }
  })
}

/**
 * @description 获取原始类型
 * @param {*} value
 * @returns {String} 类型字符串,如'String', 'Object', 'Null', 'Boolean', 'Number', 'Array'
 */
export function toRawType(value) {
  return Object.prototype.toString.call(value).slice(8, -1)
}
  • 在axios请求拦截器中使用
const httpIns = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时时间
  timeout: 15000
})

// request拦截器
httpIns.interceptors.request.use(
  config => {
    // ...略略略
    // 移除params和data中空参数
    clearEmptyParam(config)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
  • post请求:如果页面中调用createUser接口,传递如下
createUser({
    username: 'laststardust',
    password: 'laststardust666',
    is_married: '', // 非必填项,如果有值,是一个整数
})

经过axios的请求拦截器里的clearEmptyParam函数处理后,结果如下:

{
    username: 'laststardust',
    password: 'laststardust666'
}

可以看到is_married字段被移除了