Что допустимо и что не находится в запросе URI?

Фон (вопрос далее вниз)

Я гуглил это назад и вперед читающее RFCs и ТАК вопросы, пытающиеся взломать это, но я все еще не делаю получил разъем.

Таким образом, я предполагаю, что мы просто голосуем за "лучший" ответ и вот именно, или?

В основном это сводится к этому.

3.4. Компонент запроса

Компонент запроса является строкой информации, которая будет интерпретироваться ресурсом.

query = *uric

В компоненте запроса, символы""; "/", "?", ": ", " и ", " = ", " + ","", и "$" резервируются.

Первая вещь, которая пугается меня, состоит в том, что *мочевой определяется как это

uric = reserved | unreserved | escaped

reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

Это однако несколько разъяснено абзацами такой как

"Зарезервированный" класс синтаксиса выше относится к тем символам, которые позволяются в URI, но которые не могут быть позволены в конкретном компоненте универсального синтаксиса URI; они используются в качестве разделителей компонентов, описанных в Разделе 3.

Символы в "зарезервированном" наборе не резервируются во всех контекстах. Набор символов, на самом деле зарезервированных в любом данном компоненте URI, определяется тем компонентом. В целом символ резервируется, если семантика URI изменяется, если символ заменяется своим завершенным кодированием US-ASCII.

Эта последняя выборка чувствует несколько назад, но она ясно указывает, что набор зарезервированного символа зависит от контекста. Все же 3,4 состояния, что все зарезервированные символы резервируются в компоненте запроса, однако, единственные вещи, которые изменили бы семантику здесь, выходят из вопросительного знака (?), поскольку URIs не определяют понятие строки запроса.

В этой точке я разочаровался в RFCs полностью, но нашел RFC 1738 особенно интересным.

URL HTTP принимает форму:

http://<host>:<port>/<path>?<searchpart>

В <путь> и <searchpart> компоненты, "/", ";", "?" резервируются. "/" символ может использоваться в HTTP для обозначения иерархической структуры.

Я интерпретирую это, по крайней мере, относительно URL HTTP, что RFC 1738 заменяет RFC 2396. Поскольку запрос URI не имеет никакого понятия строки запроса, также интерпретация зарезервированных действительно не позволяет, позволяют мне определять строки запроса, поскольку я привык делать к настоящему времени.

Вопрос

Это все запустилось, когда я хотел передать список чисел вместе с запросом другого ресурса. Я не думал большая часть о нем и просто передал его, поскольку запятая разделила значения. К моему удивлению, хотя запятой оставили. Запрос page.html?q=1,2,3 закодированный превратился page.html?q=1%2C2%2C3 это работает, но это ужасно и не ожидало это. Именно тогда я начал проходить RFCs.

Мой первый вопрос просто, кодирование запятых действительно необходимо?

Мой ответ, согласно RFC 2396: да, согласно RFC 1738: нет

Позже я нашел связанные сообщения относительно передачи списков между запросами. Где подход csv был сбалансирован как плохо. Это обнаружилось вместо этого, (не видели это прежде).

page.html?q=1;q=2;q=3

Мой второй вопрос, действительно ли это - допустимый URL?

Мой ответ, согласно RFC 2396: нет, согласно RFC 1738: нет (; резервируется),

У меня нет проблем с передачей csv, пока это - числа, но да Вы действительно сталкиваетесь с риском необходимости закодировать и декодировать значения назад и вперед, если запятая внезапно необходима для чего-то еще. Так или иначе я попробовал вещь строки запроса точки с запятой ASP.NET, и результат не был тем, что я ожидал.

Default.aspx?a=1;a=2&b=1&a=3

Request.QueryString["a"] = "1;a=2,3"
Request.QueryString["b"] = "1"

Мне не удается видеть, как это значительно отличается от подхода csv как тогда, когда я прошу "a", я получаю строку с запятыми в нем. ASP.NET, конечно, не является ссылочной реализацией, но она еще не подвела меня.

Но самое главное - мой третий вопрос - где спецификация для этого? и что Вы сделали бы или в этом отношении не сделали бы?

91
задан outis 4 September 2013 в 18:21
поделиться

1 ответ

То, что символ зарезервирован в общем компоненте URL, не означает, что он должен быть экранирован, когда появляется в компоненте или в данных компонента. Символ также должен быть определен как разделитель в общем или специфическом для схемы синтаксисе, а его появление должно происходить в данных.

Текущим стандартом для общих URI является RFC 3986, который гласит:

2.2. Зарезервированные символы

URI включают компоненты и подкомпоненты, разграниченные символами из "зарезервированного" набора. Эти символы называются "зарезервированными", потому что они могут (или не могут) быть определены в качестве разделителей общим синтаксисом, синтаксисом, специфичным для каждой схемы, или синтаксисом, специфичным для реализации алгоритма разыменования URI. Если данные для компонента URI будут противоречить назначению зарезервированного символа в качестве разделителя [выделено автором], то противоречащие данные должны быть закодированы в процентах до формирования URI.

 зарезервированные = gen-delims / sub-delims

 gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

 sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
 / "*" / "+" / "," / ";" / "="

3.3. Path Component

[...]
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
[...]

3.4 Компонент запроса

[...]
 query = *( pchar / "/" / "?" )

Таким образом, запятые явно разрешены в строках запросов и должны экранироваться в данных только в том случае, если определенные схемы определяют их как разделитель. Схема HTTP не использует запятую или точку с запятой в качестве разделителя в строках запросов, поэтому их не нужно экранировать. Следуют ли браузеры этому стандарту - другой вопрос.

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

Что касается RFC 2396, он также допускает использование запятых без кавычек в строках запросов HTTP:

2.2. Зарезервированные символы

Многие URI включают компоненты, состоящие из определенных специальных символов или разделенные ими. специальными символами. Эти символы называются "зарезервированными", поскольку их использование в компоненте URI ограничено их зарезервированным назначением. Если данные для компонента URI противоречат зарезервированным назначением, то конфликтующие данные должны быть экранированы перед формирования URI.

Поскольку запятые не имеют зарезервированного назначения в схеме HTTP, их не нужно экранировать в данных. Замечание из § 2.3 о том, что зарезервированные символы - это те, которые меняют семантику при процентном кодировании, применимо только в общем случае; символы могут быть процентно закодированы без изменения семантики для определенных схем и все же оставаться зарезервированными.

64
ответ дан 24 November 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: