при назначении location.href, пожалуйста, объясните кодировку URL (в asp.net и firefox) - PullRequest
2 голосов
/ 22 января 2010

В некоторых JavaScript у меня есть:

var url = "find.aspx?" + "location=" + encodeURIComponent( address );
alert( url );
location.href = url;

где адресом является строка "Сиэтл, Вашингтон".

В оповещении вижу

find.aspx?Seattle%2C%20WA

как я ожидаю.

Но на стороне сервера, когда я смотрю на Request.Url, соответствующая подстрока, которую я вижу, это

find.aspx?Seattle, WA

И в окне URL Firefox я вижу

find.aspx?location=Seattle%2C WA

Итак, я получаю три разных представления, тогда как я ожидаю, что во всех трех местах я должен увидеть то, что вижу в предупреждении. Я ожидаю, что URL, который я назначаю для location.href, должен отображаться как есть в окне URL браузера и должен передаваться как есть на сервер в Request.Url (и мне нужно будет декодировать значения на сервере перед их использованием). Что происходит?

Ответы [ 3 ]

2 голосов
/ 22 января 2010

Firefox преобразует определенные закодированные символы в их буквальные формы, чтобы быть дружелюбным к пользователям. Он также преобразует пробелы, введенные в адресную строку в % 20 для сервера.

Обновление : причина, по которой Firefox не отображает незашифрованную запятую, заключается в том, что запятые разрешены в URL, а пробелы - нет, поэтому знает , что пробел будет интерпретируется однозначно, тогда как предварительно закодированная запятая отличается от некодированной запятой для некоторых серверов. см .: Можно ли использовать запятые в URL?

ASP, вероятно, пытается вам помочь, автоматически расшифровывая строку для вас.

Обновление: По умолчанию это выглядит как ASP.NET для вас кодирует Request.Url, как указано здесь: QueryString искажен после URLDecode Они также упоминают, что вы можете использовать HttpRequest.Url.Query для доступа к не декодированной версии.

Предупреждение - единственное, что не делает для вас никакой "магии".

1 голос
/ 22 января 2010

Для предупреждения вы делаете кодировку самостоятельно. Возможно, это выглядит так же, как на стороне сервера, если вы удалили encodeURIComponent.

На стороне сервера ASP.NET всегда будет отображать незашифрованную форму. Это облегчает непосредственное сопоставление с файлами, которые также имеют текст, который необходимо (не) кодировать.

Обратите внимание, что вы можете заменить каждую букву для ее представления UTF8 в кодировке URL. Это будет все тот же URL. Т.е. наберите в окне браузера следующее, и оно все равно будет работать: %66%59%6E%64.aspx?location=Seattle%2C%20WA. Чтобы кодировать только необходимые символы, используйте UrlEncode на стороне сервера, если вы сами создаете ссылку.

Кодировка URL может стать довольно сложной задачей. Вы просите объяснить это. Чтобы узнать правильное экранирование определенного персонажа, вам нужно знать, как этот персонаж выглядит в UTF8. Шестнадцатеричное значение байтов UTF-8 становится значением% XX% YY вашего письма. Иногда это один% XX, но всего может быть до шести байтов (например, некоторые китайские иероглифы).

Кодирование URL работает только в одну сторону. Никогда не кодируйте дважды и не кодируйте дважды. Это запрещено спецификацией. Кроме того, поскольку вы можете кодировать любой символ, не всегда возможно (как вы узнали) выполнить кодирование / дешифрование в обе стороны. Если вы расшифруете и снова закодируете, вполне возможно, что результирующая строка будет другой, но синтаксически одинаковой.

В HTML URL-адрес Кодировка иногда перемежается с HTML-кодировкой . То есть амперсанд действителен в HTML, но не в HTML. find.aspx?city=A&name=B становится find.aspx?city=A&name=B в URL-адресе HTML. Тем не менее, браузеры снисходительны и неправильно принимают строки в кодировке HTML.

Наконец, нет в браузере: если вы введете пробел в ссылке, даже внутри тега <a>, он уйдет за пробел (или другой символ) для вас. Кроме того, в настоящее время он будет отображать нечетные символы (é, ï и т. Д.) В адресной строке, но когда он отправляет его по HTTP, браузер правильно сделает кодировку для вас.


Обновление: об ответе на ваш вопрос о необходимости "окончательной" ссылки или доказательства.

Хотя я не смог найти ничего в интернете, я решил сам поискать его с помощью Reflector. Проходя через методы, которые устанавливают, например, HttpRequest.QueryString, вы быстро сталкиваетесь с закрытым методом HttpRequest.FillInQueryStringCollection, который затем вызывает HttpValueCollection.FillfromEncodedBytes. Несколько ближе к концу этого метода для значений вызывается HttpUtility.UrlDecode. Вывод: не называйте это сами, чтобы предотвратить двойное декодирование.

Вы можете убедиться в этом сами, загрузив Reflector и разобрав .NET-библиотеки System.Web.

0 голосов
/ 22 января 2010

Для вашего примера вы можете изменить эту строку

var url = "find.aspx?" + "location=" + encodeURIComponent( address );

до

var url = "find.aspx?" + "location=" + address;

и посмотрите адрес как есть. Но если адресная переменная содержит какой-либо символ '&', ваша переменная будет повреждена. Таким образом, вы используете encodeURIComponent для кодирования этих вещей url.

На стороне сервера все эти закодированные строки декодируются обратно. Это означает, что encodeURIComponent предназначен только для правильной отправки адресной переменной (независимо от того, содержит ли она & символ или нет) на стороне сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...