Точка с запятой как разделитель URL-запросов - PullRequest
51 голосов
/ 14 августа 2010

Хотя настоятельно рекомендуется ( источник W3C , через Википедия ) для веб-серверов поддерживать точку с запятой в качестве разделителя элементов запроса URL (в дополнение к амперсанду), это не похоже, что в целом соблюдается.

Например, сравнить

1009 *http://www.google.com/search?q=nemo&oe=utf-8

1012 *http://www.google.com/search?q=nemo;oe=utf-8

результаты. (В последнем случае точка с запятой, или была на момент написания этого текста , рассматривалась как обычный символ строки, как если бы URL был: http://www.google.com/search?q=nemo%3Boe=utf-8)

Хотя первая библиотека для разбора URL, которую я пробовал, ведет себя хорошо:

>>> from urlparse import urlparse, query_qs
>>> url = 'http://www.google.com/search?q=nemo;oe=utf-8'
>>> parse_qs(urlparse(url).query)
{'q': ['nemo'], 'oe': ['utf-8']}

Каково текущее состояние принятия точки с запятой в качестве разделителя, и каковы потенциальные проблемы или некоторые интересные заметки? (с точки зрения сервера и клиента)

Ответы [ 4 ]

19 голосов
/ 23 ноября 2016

Рекомендация W3C от 1999 устарела.В соответствии с 2014 W3C Рекомендация текущий статус таков: теперь точка с запятой недопустима в качестве разделителя параметров:

Для декодирования приложения / x-www-form-urlencoded полезных нагрузок, следует использовать следующий алгоритм.[...] Результатом этого алгоритма является отсортированный список пар имя-значение.[...]

  1. Пусть строки будут результатом строгого разделения полезной нагрузки строки на символы U + 0026 AMPERSAND (&).

Другими словами, ?foo=bar;baz означает, что параметр foo будет иметь значение bar;baz;тогда как ?foo=bar;baz=sna должен привести к foo, равному bar;baz=sna (хотя это технически незаконно, поскольку второй = должен быть экранирован до %3D).

17 голосов
/ 14 августа 2010

Пока ваш HTTP-сервер и ваше серверное приложение принимают точки с запятой в качестве разделителей, у вас все получится. Я не вижу никаких недостатков. Как вы сказали, спецификация W3C на вашей стороне :

Мы рекомендуем, чтобы разработчики HTTP-серверов, в частности, разработчики CGI, поддерживали использование ";" вместо «&» избавить авторов от необходимости экранировать символы «&» таким образом.

5 голосов
/ 12 июля 2014

Я согласен с Бобом Аманом.Спецификация W3C разработана для упрощения использования якорных гиперссылок с URL-адресами, которые выглядят как запросы GET (например, http://www.host.com/?x=1&y=2).В этом контексте амперсанд конфликтует с системой для ссылок на символьные объекты, которые начинаются с амперсанда (например, ").Поэтому W3C рекомендует, чтобы веб-серверы разрешали использовать точку с запятой в качестве разделителя полей вместо амперсанда, чтобы было проще писать эти URL-адреса.Но это решение требует, чтобы авторы помнили, что амперсанд должен быть заменен чем-то, и что ; является одинаково допустимым разделителем полей, хотя веб-браузеры универсально используют амперсанды в URL при отправке форм.Возможно, это сложнее, чем помнить о замене амперсанда на & в этих ссылках, как это было бы сделано в других местах документа.

Что еще хуже, пока все веб-серверы не разрешают использовать точки с запятой в качестве разделителей полей, разработчики URL-адресов могут использовать этот ярлык только для одних хостов и должны использовать & для других.Им также придется изменить свой код позже, если данный хост прекратит использование разделителей точки с запятой.Это, конечно, сложнее, чем просто использовать &, который будет работать для каждого сервера навсегда.Это, в свою очередь, устраняет любые стимулы для веб-серверов использовать точки с запятой в качестве разделителей полей.Зачем беспокоиться, когда все уже меняют амперсанд на & вместо ;?

2 голосов
/ 25 января 2016

Короче говоря, HTML - большой беспорядок (из-за его снисходительности), и использование точек с запятой помогает упростить это МНОГО. Я полагаю, что когда я учитываю обнаруженные мной сложности, использование амперсандов в качестве разделителя делает весь процесс примерно в три раза сложнее, чем использование точек с запятой вместо разделителей!

Я программист .NET, и, насколько мне известно, .NET не по своей сути разрешает ';' разделители, поэтому я написал свои собственные методы синтаксического анализа и обработки, потому что я увидел огромное значение в использовании точек с запятой, а не в уже проблемной системе использования амперсандов в качестве разделителей. К сожалению, очень уважаемые люди (как @Bob Aman в другом ответе) не видят ценности в том, почему использование точки с запятой намного лучше и намного проще, чем использование амперсандов. Итак, теперь я поделюсь несколькими моментами, чтобы, возможно, убедить других уважаемых разработчиков, которые еще не осознают ценность использования точек с запятой:

Использование строки запроса, подобной '? A = 1 & b = 2' на HTML-странице, является неправильным (без предварительного кодирования HTML), но в большинстве случаев это работает. Это, однако, только из-за того, что большинство браузеров являются толерантными, и этот допуск может привести к трудно обнаруживаемым ошибкам, когда, например, значение пары «ключ-значение» публикуется в URL-адресе HTML-страницы без надлежащей кодировки (непосредственно как «? a = 1 & b = 2 'в источнике HTML). Строка QueryString типа «? Who = me + & + you» тоже проблематична.

Мы, люди, можем иметь предубеждения и можем не соглашаться с нашими предубеждениями в течение всего дня, поэтому признание наших предубеждений очень важно. Например, я согласен, что я просто думаю отделить от ';' выглядит «чище». Я согласен с тем, что мое «чистое» мнение является чисто предвзятым. И другой разработчик может иметь одинаково противоположный и одинаково действительный уклон. Так что мой уклон по этому одному пункту не более правильный, чем противоположный уклон.

Но, учитывая непредвзятую поддержку точки с запятой, делающей жизнь каждого человека в долгосрочной перспективе, не может быть правильно оспорена, если принять во внимание всю картину. Короче говоря, использование точек с запятой делает жизнь проще для каждого , за одним исключением: небольшое препятствие для привыкания к чему-то новому. Это все. Всегда сложнее что-либо изменить. Но трудность внесения изменений меркнет по сравнению с продолжающейся трудностью продолжения использования &.

Использование; как разделитель QueryString делает его намного проще. Сепараторы с амперсандом вдвое сложнее правильно кодировать , чем при использовании точек с запятой. (Я думаю) большинство реализаций не кодируются должным образом, поэтому большинство реализаций не вдвое сложнее. Но тогда отслеживание и исправление ошибок приводит к снижению производительности. Здесь я указываю на 2 отдельных этапа кодирования, необходимых для правильного кодирования QueryString, когда & является разделителем:

  • Шаг 1. URL кодирует и ключи, и значения строки запроса.
  • Шаг 2. Объедините ключи и значения, такие как 'a = 1 & b = 2', после того, как они закодированы с URL-адреса с шага 1.
  • Шаг 3: Затем HTML кодирует всю строку QueryString в исходном HTML-коде страницы.

Таким образом, специальное кодирование должно быть выполнено дважды для правильного (безошибочного) кодирования URL, и не только, но кодирования - это два разных, разных типа кодирования. Первый - это кодировка URL, а второй - кодировка HTML (для исходного кода HTML). Если что-то из этого неверно, то я могу найти вам ошибку. Но шаг 3 отличается для XML. Для XML вместо этого требуется кодировка символов XML (которая практически идентична). Я хочу сказать, что последняя кодировка зависит от контекста URL, будь то на веб-странице HTML или в документации XML.

Теперь с гораздо более простыми разделителями точек с запятой, процесс выглядит так:

  • 1: URL кодирует ключи и значения,
  • 2: объединить значения вместе. (Без кодирования для шага 3.)

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

Другая сложность в реальном использовании заключается в написании разметки документации XML в моем исходном коде как на C #, так и на VB.NET. Поскольку & должен быть закодирован, это буквально затягивает мою производительность. Этот дополнительный шаг 3 также затрудняет чтение исходного кода. Таким образом, этот трудный для чтения дефицит применяется не только к HTML и XML, но также и к другим приложениям, таким как код C # и VB.NET, потому что их документация использует документацию XML. Таким образом, сложность кодирования шага № 3 распространяется и на другие приложения.

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

Возможно, это не было слишком запутанным. Но вся путаница или трудность связана с использованием символа разделения, который должен кодироваться в формате HTML. Таким образом, «&» является виновником. И точка с запятой снимает все это осложнение.

...