De forma predeterminada, cuando un objeto de JavaScript contiene un objeto de fecha, Axios lo serializa en UTC. Esto significa que la hora transmitida se convierte utilizando la zona horaria. Esto no funciona para mi caso de uso. Necesito enviar la hora sin la conversión de zona horaria a UTC.
Implementé un serializador personalizado basado en #1548 , pero no tiene ningún efecto. Verifiqué que la configuración se está modificando, pero cuando miro la carga útil de la solicitud, las fechas todavía usan UTC (2022-02-03T04: 59: 00.000Z).
Nota: mi lógica es más complicada, estoy usando toLocalString() en el código a continuación para simplificar el ejemplo.
const a = axios.create() a.interceptors.request.use((config) => { config.paramsSerializer = (params) => qs.stringify(params, { serializeDate: (date: Date) => date.toLocaleString(), }) return config })¿Alguien entiende por qué no puedo anular el comportamiento predeterminado y usar mi propio formato de fecha?
Entorno Axios Versión 0.21.1
No es Axios quien hace la serialización. Date implementa toJSON() que se emplea cuando sus objetos (que contienen fechas) se serializan a través de JSON.stringify() ...
Las instancias de
Dateimplementan la funcióntoJSON()devolviendo una cadena (igual quedate.toISOString()). Por lo tanto, se tratan como cadenas.
El paramSerializer es para serializar parámetros de consulta , por lo que no se aplicó a su cuerpo de solicitud.
Para transformar el cuerpo de la solicitud, desea utilizar transformRequest .
Aquí hay un transformador recursivo genérico que encuentra fechas y las asigna a cadenas localizadas
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 }Luego puede registrar este transformador en su instancia de Axios, que se aplicará a todas las solicitudes PUT, POST, PATCH y DELETE.
const instance = axios.create({ transformRequest: [ dateTransformer ].concat(axios.defaults.transformRequest) }) instance.post(url, data)Si la versión genérica parece un poco torpe, puede transformar el objeto usted mismo antes de publicarlo...
const body = { date: new Date() } axios.post(url, { ...body, date: body.date.toLocaleString() })o registrar un transformador en línea
axios.post(url, body, { transformRequest: [ data => ({ ...data, date: data.date.toLocaleString() }), ...axios.defaults.transformRequest ] })Esta es la respuesta más excelente de Phil con pequeñas modificaciones para mecanografiado. Esto es para axios 0.21.1. (En la versión 0.23.1+ parece que AxiosTransformer fue refactorizado a 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[])], })