Как правильно использовать 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'})
}
- Установить
qs
перейдите по этой ссылке - Подробнее о paramsSerializer читайте в документе axios
- Формат редактирования параметров: подробнее см. В документе, посвященном строкам qs
Это поведение было добавлено в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
}
})