Как правильно использовать axios params с массивами

Как добавить индексы в массив в строке запроса?

Я пытался отправить данные так:

axios.get('/myController/myAction', { params: { storeIds: [1,2,3] })

И я получил этот URL:

http://localhost/api/myController/myAction?storeIds[]=1&storeIds[]=2&storeIds[]=3

Итак, я должен получить этот URL:

http://localhost/api/myController/myAction?storeIds[0]=1&storeIds[1]=2&storeIds[2]=3

Что я должен добавить в мои параметры params, чтобы получить этот URL?

19 ответов

Ты можешь использовать paramsSerializer и сериализовать параметры с помощью https://www.npmjs.com/package/qs

axios.get('/myController/myAction', {
  params: {
    storeIds: [1,2,3]
  },
  paramsSerializer: params => {
    return qs.stringify(params)
  }
})

Не добавляя дополнительных библиотек и не используя ES6, вы можете написать:

axios.get(`/myController/myAction?${[1,2,3].map((n, index) => `storeIds[${index}]=${n}&`)}`);

Большое спасибо за ответ Нику Кристе, для моего случая API требует таких параметров:

params: {
  f: {
    key: 'abc',
    categories: ['a','b','c']
   },
  per_page: 10
}

Метод - GET, и для этого API требуется формат: API?f[key]=abc&f[categories][]=a&f[categories][]=b... Итак, я назначил paramsSerializer для axios следующим образом:

config.paramsSerializer = p => {
      return qs.stringify(p, {arrayFormat: 'brackets'})
    }

Это поведение было добавлено вaxiosначиная с версии1.0.0. См. https://github.com/axios/axios/tree/v1.0.0#request-config.

Вот пример использования вашего примера кода:

      axios.get('/myController/myAction', {
  params: { storeIds: [1,2,3] },
  paramsSerializer: {
    indexes: true, // use brackets with indexes
  }
)

Полученные параметры запроса будут иметь индексы внутри скобок:

      /myController/myAction?storeIds[0]=1&storeIds[1]=2&storeIds[2]=3

ДругойparamsSerializer.indexesценностиnull(без скобок):

      axios.get('/myController/myAction', {
  params: { storeIds: [1,2,3] },
  paramsSerializer: {
    indexes: null, // no brackets at all
  }
)
// /myController/myAction?storeIds=1&storeIds=2&storeIds=3

И по умолчаниюfalse(скобки без индексов):

      axios.get('/myController/myAction', {
  params: { storeIds: [1,2,3] },
  paramsSerializer: {
    indexes: false, // brackets but no indexes
  }
)
// /myController/myAction?storeIds[]=1&storeIds[]=2&storeIds[]=3

В моем случае я использую функцию массива ES6. Элемент массива заставляет строку запроса использовать функцию уменьшения. Массив объектов тоже работает.

const storeIds = [1,2,3]
axios.get('some url', {
  params: {
    storeIds: storeIds.reduce((f, s) => `${f},${s}`)
  }
})

Здесь много хороших ответов. Но я просто хотел поделиться тем, что я в итоге использовал: (работает как шарм даже с другими параметрами, не являющимися массивами, в вашем объекте)

Вот мой объект параметров:

      params: {
    city: '335471',
    size: 4,
    page: 1,
    type: [1, 2, 3, 4, 5, 6],
}

Это метод получения аксиомов:

      $axios.get('/some/api/endpoint/', {
    params,
    paramsSerializer: (params) => parseParams(params),
})
      function parseParams(params) {
  const keys = Object.keys(params)
  let options = ''

  keys.forEach((key) => {
    const isParamTypeObject = typeof params[key] === 'object'
    const isParamTypeArray = isParamTypeObject && params[key].length >= 0

    if (!isParamTypeObject) {
      options += `${key}=${params[key]}&`
    }

    if (isParamTypeObject && isParamTypeArray) {
      params[key].forEach((element) => {
        options += `${key}=${element}&`
      })
    }
  })

  return options ? options.slice(0, -1) : options
}

И, наконец, используя этот метод, вы отправите этот запрос:

      https://yourwebsite.com/api/some/api/endpoint/?city=335471&size=4&page=1&type=1&type=2&type=3&type=4&type=5&type=6

источник: https://github.com/axios/axios/issues/604#issuecomment-420135579

Я переписал существующий paramSerializer, поставляемый в axios. Следующий фрагмент кода выполняет ту же сериализацию, помещая индексы в квадратные скобки. Я пробовал qs, но он несовместим с моим сервером подключения python (для строковых параметров JSON).

      const rcg = axios.create({
    baseURL: `${url}/api`,
    paramsSerializer: params => {
        const parts = [];

        const encode = val => {
            return encodeURIComponent(val).replace(/%3A/gi, ':')
                .replace(/%24/g, '$')
                .replace(/%2C/gi, ',')
                .replace(/%20/g, '+')
                .replace(/%5B/gi, '[')
                .replace(/%5D/gi, ']');
        }

        const convertPart = (key, val) => {
            if (val instanceof Date)
                val = val.toISOString()
            else if (val instanceof Object)
                val = JSON.stringify(val)

            parts.push(encode(key) + '=' + encode(val));
        }

        Object.entries(params).forEach(([key, val]) => {
            if (val === null || typeof val === 'undefined')
                return

            if (Array.isArray(val))
                val.forEach((v, i) => convertPart(`${key}[${i}]`, v))
            else
                convertPart(key, val)
        })

        return parts.join('&')
    }
});

В моем случае я использую что-то вроде этого

const params = array.map((v)=>{
            return `p=${v}&`
        })

Только конкат params.join('') на URL-адрес, по которому вы получаете данные:

`url_to_get?${params.join('')`

На моем сервере в ASP.net я получаю это

[FromUri] string [] p

вы можете создать функцию какparseParamsкоторый может отправлять параметры этой функции и сериализовать ее.

Этот ответ вдохновлен ответом @Nicu Criste .

Но может быть не связано с опубликованным вопросом.

Следующий код использовался для генерации параметров запроса с повторяющимися ключами, которые были предоставлены с массивом объектов.

Примечание. Если вы являетесь разработчиком с фобией пакетов , используйте следующий подход с осторожностью: как и в случае с UrlSearchParams, поддержка зависит от разных браузеров и платформ .

      const queryParams = [{key1: "value1"}, {key2: "value2"}]

axios.get('/myController/myAction', {
  params: queryParams,
  paramsSerializer: params => {
    return params.map((keyValuePair) => new URLSearchParams(keyValuePair)).join("&")
  }
})

// request -> /myController/myAction?key1=value1&key2=value2

В React мне нужно было использовать axios с параметрами в массиве. Это был параметр запроса:

"fields[0]=username&fields[1]=id&populate[photo][fields][0]=url&populate[job][fields][1]=Job"

отправить с помощью axios, для этого я установил CLI

npm install qs Подробнее о qs

и объявил

const qs = require('qs');

после
const query = qs.stringify({
fields: ['username', 'id'],
populate: {
photo: {
fields: ['url']
},
job: {
fields: ['Job']
}
}
}, {
encodeValuesOnly: true
});


и, наконец, я назвал аксиомы следующим образом:
axios.create({
baseURL: "http://localhost:1337/api/",
}).get(`/users?${query}`) // this parameter show all data
.then((response) => console.log(response.data))
.catch((err) => {
setError(err);
});

Используйте JSON.stringify, чтобы связать массив в строку, а затем отправить arrat в параметрах.

let storeIds: [1,2,3];
axios.get('/myController/myAction', { params: { storeIds: JSON.stringify(storeIds) })

По сути, чтение из документов https://axios-http.com/docs/req_config
— это необязательная функция, которую мы должны использовать, если сериализация по умолчаниюparamsсделаноaxiosне так, как ожидалось.

Мы можем использовать библиотеки сериализации (что я считаю лучшим подходом) для сериализации параметров в функции paramsSerializer в соответствии с нашими потребностями.
Давайте посмотрим на пример. Предположим, что параметры похожи на ...

      {
      params: {
        delay: 1,
        ar:[1,2,3]
      }
}

тогда вы получите queryString следующим образом?delay=1&ar[]=1&ar[]=2&ar[]=3когда вы делаете запрос, но вы можете захотеть так?delay=1&ar[0]=1&ar[1]=2&ar[2]=3

поэтому, чтобы получить строку запроса в соответствии с нашим форматом. мы можем использоватьqs https://www.npmjs.com/search?q=qs и сериализуем наши параметры
вparamsSerializerфункционировать, как показано ниже

      {
      method: "GET",
      params: {
        delay: 1,
        ar:[1,2,3]
      },
      paramsSerializer: (params) => {
        return qs.stringify(params,{
          encodeValuesOnly: true
          });
      }
},

Я знаю, что этот подход не очень хорош, и я не знаю, какие у него могут быть недостатки, но я попробовал это, и это сработало:

перед выполнением запроса подготовьте параметры:

        let params = '?';

  for (let i = 0; i < YOUR_ARRAY.length; i++) {  // In this case YOUR_ARRAY == [1, 2, 3]
    params += `storeIds=${YOUR_ARRAY[i]}`;  // storeIds is your PARAM_NAME
    if (i !== YOUR_ARRAY.length - 1) params += '&';
  }

И затем сделайте запрос следующим образом:

      axios.get('/myController/myAction' + params)

У меня была проблема, которую я хотелaxiosвообще исключить скобки. В итоге я установилparamsSerializer.indexesполе дляnull. Вы можете установить индексы по своему усмотрению, установивindexesкtrue.

      axiosInstance.defaults.paramsSerializer = {
 
  // e.g. instead of
  // storeIds[]=1&storeIds[]=2&storeIds[]=3

  // you get
  // storeIds[0]=1&storeIds[1]=2&storeIds[2]=3

  // with
  indexes: true
};

Его также можно установить для каждого запроса, поскольку он является частьюAxiosRequestConfigинтерфейс:

      axios.get(
  '/myController/myAction',
  { 
    params: { 
      storeIds: [1,2,3] 
    }, 
    paramsSerializer: {
 
      indexes: true
    }
  }
)

Я немного запутался в использовании paramSerializer. Прежде чем искать «правильный способ» использования аксиомов со строкой запроса массива в Google, я сделал следующее и приступил к работе:

      var options = {};
var params = {};
for(var x=0;x<Products.length;x++){
   params[`VariableName[${x}]`] = Products[x].Id;
}
options.params = params;

axios.get(`https://someUrl/`, options)...

Он собирается создать такие параметры строки запроса, как:

      VariableName[0]=XPTO,VariableName[1]=XPTO2

который большинство веб-серверов ожидали как формат массива

В моем случае в мою кодовую базу уже был внедрен jQuery. Поэтому я просто использовал предопределенный метод.

jQuery.param(Object)

Мне так было лучше:

axios.get('/myController/myAction', {
params: { storeIds: [1,2,3] + ''}

})

Это работает для меня:

      axios.get("/financeiro/listar",{
        params: {
          periodo: this.filtro.periodo + "",
          mostrarApagados: this.filtro.mostrarApagados,
          mostrarPagos: this.filtro.mostrarPagos,
          categoria: this.filtro.categoria,
          conta: this.filtro.conta
        }
      })

Другие вопросы по тегам