在Axios中自定义日期序列化

x6h2sr28  于 2023-08-04  发布在  iOS
关注(0)|答案(3)|浏览(160)

默认情况下,当JavaScript对象包含Date对象时,Axios会将其序列化为UTC。这意味着使用时区转换传输的时间。这不适用于我的用例。我需要发送没有时区转换为UTC的时间。
我实现了一个基于#1548的自定义序列化器,但它没有任何效果。我已经验证了配置正在被修改,但是当我查看请求负载时,日期仍然使用UTC(2022-02- 03 T04:59:00.000Z)。
注意:我的逻辑更复杂,我在下面的代码中使用toLocalString()来简化示例。

const a = axios.create()
a.interceptors.request.use((config) => {
  config.paramsSerializer = (params) =>
    qs.stringify(params, {
      serializeDate: (date: Date) => date.toLocaleString(),
    })
  return config
})

字符串
有人明白为什么我不能覆盖默认行为,并使用自己的日期格式?
环境Axios版本0.21.1

dfddblmv

dfddblmv1#

这不是Axios做的序列化。Date实现了toJSON(),当您的对象(包含日期)通过JSON序列化时使用。
Date的示例通过返回一个字符串(与date.toISOString()相同)来实现toJSON()函数。因此,它们被视为字符串。
paramSerializer用于序列化queryparams,这就是为什么它不适用于您的请求主体。
要转换请求体,您需要使用transformRequest
下面是一个通用的递归Transformer,它可以查找日期并将其Map到本地化的字符串

import axios, { AxiosRequestTransformer } from "axios"

const dateTransformer: AxiosRequestTransformer = data => {
  if (data instanceof Date) {
    // do your specific formatting here
    return data.toLocaleString()
  }
  if (Array.isArray(data)) {
    return data.map(val => dateTransformer(val))
  }
  if (typeof data === "object" && data !== null) {
    return Object.fromEntries(Object.entries(data).map(([ key, val ]) =>
      [ key, dateTransformer(val) ]))
  }
  return data
}

字符串
然后,您可以在Axios示例中注册此Transformer,它将应用于所有PUT,POST,PATCH和DELETE请求。

const instance = axios.create({
  transformRequest: [ dateTransformer ].concat(axios.defaults.transformRequest)
})

instance.post(url, data)


如果通用版本看起来有点笨拙,您可以在发布之前自己转换对象…

const body = {
  date: new Date()
}

axios.post(url, {
  ...body,
  date: body.date.toLocaleString()
})


或注册在线Transformer

axios.post(url, body, {
  transformRequest: [
    data => ({
      ...data,
      date: data.date.toLocaleString()
    }),
    ...axios.defaults.transformRequest
  ]
})

zphenhs4

zphenhs42#

这是Phil最出色的回答,只是对 typescript 做了一些小的修改。这是针对axios 0.21.1的。(在0.23.1+版本中,AxiosTransformer看起来像是被重构为AxiosRequestTransformer

const dateTransformer = (data: any): any => {
  if (data instanceof Date) {
    // do your specific formatting here
    return data.toLocaleString()
  }
  if (Array.isArray(data)) {
    return data.map(dateTransformer)
  }
  if (typeof data === 'object' && data !== null) {
    return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, dateTransformer(value)]))
  }
  return data
}
const axiosInstance = axios.create({
  transformRequest: [dateTransformer, ...(axios.defaults.transformRequest as AxiosTransformer[])],
})

字符串

1sbrub3j

1sbrub3j3#

const replacer = function(this: any, key: string, value: any) {
        if (this[key] instanceof Date) {
           return moment(this[key]).format("YYYY-MM-DD HH:mm:ss")
        }    
        return value
    }
    
    const axiosInstance = axios.create({
      transformRequest: [(data, headers) => JSON.stringify(data, replacer), ...(axios.defaults.transformRequest as AxiosRequestTransformer[])]
    })

字符串

相关问题