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

275

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

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

Кроме того, в соответствии с этим post answer автор предполагает, что поддержка строки запроса для массивов не определена. Это точно?

EDIT:

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

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

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

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

  • 0
    Какие рамки вы используете? В некоторых инфраструктурах есть методы, помогающие передавать массивы в строки запросов.
  • 0
    @ keyboardP - PHP и Javascript, в зависимости от варианта использования
Показать ещё 2 комментария
Теги:
arrays
query-string

8 ответов

341
Лучший ответ

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

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

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

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

Примеры форм

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

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

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

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

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

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


UPDATE

Как отмечают комментаторы, это очень специфично для конкретной структуры. Некоторые примеры:

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

?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"

Angular:

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

(Angular обсуждение)

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


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

  • 2
    Я думаю, что причина того, что эта функциональность не документирована в общих источниках, таких как Wiki или W3C, заключается в том, что она вообще не поддерживается веб-фреймворками. PHP и я думаю, что Rails автоматически конвертирует несколько параметров запроса «key []» в массив. Другие нет.
  • 2
    Модуль строки запроса nodejs использует форму ?cars=Saab&cars=Audi Cars ?cars=Saab&cars=Audi
Показать ещё 13 комментариев
31

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

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

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

  • 0
    ОК, спасибо за разъяснения. Можете ли вы увидеть мой пересмотренный вопрос - нужно ли делать p1 ... pn для ключей, или я могу просто назвать несколько ключей 'p', и таким образом я бы знал, что они все принадлежат одному и тому же массиву?
  • 1
    Вы можете использовать то же имя; stackoverflow.com/questions/2203430/… или просто p = aa, bb, cc, что является наиболее очевидным способом, как прокомментировал Серодис.
Показать ещё 2 комментария
15

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

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

  1. Есть способ PHP, который использует квадратные скобки ([, ]) в URL-запросах. Например, такой запрос, как ?array_name[]=item&array_name[]=item_2, как говорят, работает, хотя и плохо документирован, с помощью PHP, автоматически преобразующего его в массив. Источник: https://stackoverflow.com/questions/6243051/how-to-pass-an-array-within-a-query-string

  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.
6

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

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

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

2

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

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

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

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

В ссылке на атрибут есть value->

к = "/фильтр/обр? фруктах = яблоко & фрукты = бананового"

Маршрут может обрабатывать this->

Путь = "/фильтр/: обры"

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

к = "фильтр/обр? фруктах = яблоко и фрукты = банан и овощи = картофель и овощи = лук"

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

СКРИНШОТ

Изображение 770

1

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

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

?>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню