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

355

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

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

Также, согласно этому посту , автор предполагает, что поддержка строк в массивах не определена. Это точно?

РЕДАКТИРОВАТЬ:

Основываясь на ответе @ Alex, стандартного способа сделать это не существует, поэтому я продолжу: как легко определить, что параметр, который я читаю, представляет собой массив как в PHP, так и в Javascript ?

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

?myarray=value1&myarray=value2&myarray=value3...

Или это будет плохая практика?

Ярина
источник
Какие рамки вы используете? В некоторых средах есть методы, помогающие передавать массивы в строки запросов.
клавиатураP
@ keyboardP - PHP и Javascript, в зависимости от
варианта
2
Зачем вам это делать, когда вы можете просто сделать:? Myarray = value1, value2, value3
Serodis
18
@seroids: что делать, если ему нужно ввести запятые, знаки вопроса, знаки равенства и непечатные символы?
Ягода Цакала

Ответы:

430

Вот что я понял:

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

Три возможных способа отправки многозначных полей или массивов:

  • ?cars[]=Saab&cars[]=Audi (Лучший способ - PHP читает это в массив)
  • ?cars=Saab&cars=Audi (Плохой путь - PHP будет регистрировать только последнее значение)
  • ?cars=Saab,Audi (Не пробовал это)

Примеры форм

В форме многозначные поля могут принимать форму поля выбора, установленного в несколько значений :

<form> 
    <select multiple="multiple" name="cars[]"> 
        <option>Volvo</option> 
        <option>Saab</option> 
        <option>Mercedes</option> 
    </select>
</form>

(ПРИМЕЧАНИЕ. В этом случае было бы важно назвать имя some_name[]элемента управления select , чтобы результирующие переменные запроса были зарегистрированы PHP как массив)

... или как несколько скрытых полей с одинаковым именем :

<input type="hidden" name="cars[]" value="Volvo">
<input type="hidden" name="cars[]" value="Saab">
<input type="hidden" name="cars[]" value="Mercedes">

ПРИМЕЧАНИЕ. Использование field[]нескольких значений действительно плохо документировано. Я не вижу упоминаний об этом в разделе о многозначных ключах в строке запроса - в Википедии или в документах W3C, посвященных множественному выбору входных данных.


ОБНОВИТЬ

Как отметили комментаторы, это очень сильно зависит от структуры. Некоторые примеры:

Строка запроса:

?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3

Рельсы:

"list_a": "3", 
"list_b":[
    "1",
    "2",
    "3"
  ], 
"list_c": "1,2,3"

Угловой:

 "list_a": [
    "1",
    "2",
    "3"
  ],
  "list_b[]": [
    "1",
    "2",
    "3"
  ],
  "list_c": "1,2,3"

(Угловая дискуссия )

Смотрите комментарии для примеров в node.js , Wordpress , ASP.net


Поддержание порядка: еще одна вещь, которую следует учитывать, это то, что если вам нужно поддерживать порядок ваших элементов (т.е. массив как упорядоченный список), у вас действительно есть только одна опция, которая передает разделенный список значений и явно конвертирует его в массив сам.

Ярина
источник
3
Я думаю, что причина того, что эта функциональность не документирована в общих источниках, таких как Wiki или W3C, заключается в том, что она вообще не поддерживается веб-фреймворками. PHP и я думаю, что Rails автоматически конвертирует несколько параметров запроса «key []» в массив. Другие нет.
Карл Дж
3
Модуль строки запроса nodejs использует ?cars=Saab&cars=Audiформу
SystemParadox
53
В экспрессе (node.js) оба ?cars=Saab&cars=Audiи ?cars[]=Saab&cars[]=Audiпревращаются в массивы. Тем не менее, ?cars=Saabзаканчивается как строка, но ?cars[]=Saabпредставляет собой массив с одним элементом.
Тревор Диксон
5
Можете ли вы установить ключи, используя этот подход? А как насчет многомерных массивов?
Qwerty
5
ASP.NET MVC, по-видимому, не читает формат. ?cars[]=Saab&cars[]=AudiКвадратные скобки либо отсутствуют, либо квадратные скобки нуждаются в индексах /
г-н Флиббл
37

Строка запроса содержит текстовые данные, поэтому нет другого выбора, кроме как взорвать массив, правильно его кодировать и передать в выбранном вами формате представления:

p1=value1&pN=valueN...
data=[value1,...,valueN]
data={p1:value1,...,pN:valueN}

а затем декодировать его в коде на стороне сервера.

Алекс К.
источник
ОК, спасибо за разъяснения. Можете ли вы увидеть мой пересмотренный вопрос - нужно ли делать p1 ... pn для ключей, или я могу просто назвать несколько ключей 'p', и таким образом я бы знал, что они все принадлежат одному и тому же массиву?
Ярин
1
Вы можете использовать то же имя; stackoverflow.com/questions/2203430/… или просто p = aa, bb, cc, что является наиболее очевидным способом, как прокомментировал Серодис.
Алекс К.
очень полезно с JSON.stringifyи JSON.parse!
charliebrownie
1
Простой и распространенный формат представления - это JSON, в PHP используется json_encodethen rawurlencodeи json_decodeна другой странице.
Эдвард
20

Я не думаю, что есть стандарт.
Каждая веб-среда предоставляет свой «стандарт» для таких вещей. Кроме того, URL-адрес обычно слишком короткий для чего-либо (ограничение 256 байтов в некоторых браузерах). Конечно, более длинные массивы / данные могут быть отправлены с запросами POST.

Однако есть несколько методов:

  1. Есть способ PHP, который использует квадратные скобки ( [, ]) в запросах URL. Например, такой запрос, как ?array_name[]=item&array_name[]=item_2говорят, работает, несмотря на то, что он плохо документирован, а PHP автоматически преобразует его в массив. Источник: https://stackoverflow.com/a/9547490/3787376

  2. Форматы обмена объектными данными (например, JSON - официальный веб-сайт , документация PHP ) также могут использоваться, если у них есть методы преобразования переменных в и из строк, как это делает JSON.
    Кроме того, url-кодировщик (доступный для большинства языков программирования) необходим для запросов HTTP get для правильного кодирования строковых данных.

Хотя «метод квадратных скобок» прост и работает, он ограничен PHP и массивами.
Если требуются другие типы переменных, такие как классы или передаваемые переменные в строках запроса на языке, отличном от PHP, рекомендуется использовать метод JSON.

Пример в PHP метода JSON (метод 2):

$myarray = array(2, 46, 34, "dfg");
$serialized = json_encode($myarray)
$data = 'myarray=' . rawurlencode($serialized);
// Send to page via cURL, header() or other service.

Код для получения страницы (PHP):

$myarray = json_decode($_GET["myarray"]); // Or $_POST["myarray"] if a post request.
Ягода Цакала
источник
1
Express.js также поддерживает обозначения в квадратных скобках, протестировано на 4.13.4.
Стив Келет
7

Я чувствую, что это будет полезно для тех, кто ищет передачу массива в строке запроса сервлету. Я протестировал приведенную ниже строку запроса и смог получить значения массива с помощью req.getgetParameterValues ​​(); метод. Ниже приведена строка запроса, которую я пропустил через браузер.

  http://localhost:8080/ServletsTutorials/*.html? 
  myname=abc&initial=xyz&checkbox=a&checkbox=b

флажок - это мой массив параметров здесь.

вара
источник
5

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

В ссылке, чтобы атрибут имел значение:

to="/filter/arr?fruits=apple&fruits=banana"

Маршрут может справиться с этим:

path="/filter/:arr"

Для нескольких массивов:

to="filter/arr?fruits=apple&fruits=banana&vegetables=potato&vegetables=onion"

Маршрут остается прежним.

СКРИНШОТ

введите описание изображения здесь

Алия
источник
2

Вы упоминаете PHP и Javascript в своем вопросе, но не в тегах. Я дошел до этого вопроса с намерением передать массив в действие MVC.Net.

Я нашел ответ на свой вопрос здесь : ожидаемый формат - это тот, который вы предложили в своем вопросе, с несколькими параметрами, имеющими одно и то же имя.

DCShannon
источник
2
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
Андрей
@ Andrew Это не просто ссылка, ответ. «Ожидаемый формат - тот, который вы предложили в своем вопросе, с несколькими параметрами, имеющими одно и то же имя».
DCShannon
2

Я использую React и Rails. Я сделал:

JS

  let params = {
    filter_array: ['A', 'B', 'C']
  }

  ...

  //transform params in URI

  Object.keys(params).map(key => {
    if (Array.isArray(params[key])) {
      return params[key].map((value) => `${key}[]=${value}`).join('&')
    }
  }
  //filter_array[]=A&filter_array[]=B&filter_array[]=C
Linielson
источник
1

Вы можете использовать http_build_query для генерации строки запроса в кодировке URL из массива в PHP. Хотя результирующая строка запроса будет расширена, вы можете выбрать уникальный разделитель, который вы хотите использовать в качестве параметра http_build_queryметода, поэтому, когда дело доходит до декодирования, вы можете проверить, какой разделитель использовался. Если бы он был уникальным, то это будет строка запроса массива, иначе это будут обычные строки запроса.

keyboardP
источник
1

Хотя в части URL нет стандарта, для JavaScript есть один стандарт. Если вы передаете объекты, содержащие массивы URLSearchParams, и вызываете toString()их, он преобразует их в список элементов, разделенных запятыми:

let data = {
  str: 'abc',
  arr: ['abc', 123]
}

new URLSearchParams(data).toString();  # ?str=abc&arr=abc,123
Жоао Хаас
источник
0

Проверьте parse_stringфункцию http://php.net/manual/en/function.parse-str.php

Он вернет все переменные из строки запроса, включая массивы.

Пример с php.net:

<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
parse_str($str);
echo $first;  // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz

parse_str($str, $output);
echo $output['first'];  // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

?>
Дэн Мерфитт
источник