Кодирование компонентов URL с помощью амперсанда & - PullRequest
6 голосов
/ 02 июля 2010

Здесь очень простой вопрос:

У меня есть программа, в которой кто-то вводит строку M&S в форму и запускает запрос. Я понимаю, что & является зарезервированным символом и поэтому должен быть закодирован. Проблема в том, что в некоторых контекстах требуется дважды кодирование.

Если URL используется в событии javascript onClick, нормальное кодирование URL, похоже, работает нормально (здесь оператор может щелкнуть заголовок столбца для сортировки):

<td onClick="AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=161')">

Однако, если URL используется в привязке (хотя привязка на самом деле использует AJAX), ему, вероятно, потребуется кодирование дважды:

<a href="javascript:AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')" title='Refresh'>Refresh</a>

Оба примера выше работают нормально. Однако они являются сгенерированными вручную тестами. К сожалению, в приложении, когда я действительно генерирую URL, я не знаю, как он будет использоваться.

Если я закодирую параметр URL один раз (M%26S), он отлично работает в onClick. Но при использовании этого способа в привязке сервер видит URL-адрес как ...Qry147=M&S&sortmethod1=147... - поэтому он должен быть незашифрован перед передачей на сервер.

Если я дважды его кодирую (M%2526S), якорь работает, но для onClick сервер видит ...Qry147=M%2526S....

У меня такое ощущение, что я что-то здесь упускаю. Есть ли способ сделать эту работу одинаковой в обоих случаях?

Ответы [ 3 ]

8 голосов
/ 02 июля 2010

Если вы построите весь HTML-текст с помощью простых шагов, некоторые трудности исчезнут. Итак, используя ваш пример, вы хотите закодировать следующий параметр запроса:

M&S

Когда вы встраиваете эту строку в качестве параметра запроса в URL, вам нужно ее кодировать, как вы уже знаете. Строка urlencoded M%26S. Полный URL-адрес выглядит следующим образом:

http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=147

Теперь этот URL встроен в код JavaScript, и в этом случае вам нужны только одинарные кавычки на обоих концах:

'http://10.0.0.195/program.exe?Qry147=M%26S&sortmethod1=147'

Весь код JavaScript выглядит следующим образом:

AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')

Теперь весь этот текст используется в контексте HTML, который интерпретируется как URL, поэтому вам нужно снова его кодировать:

AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&sortmethod1=147')

И, наконец, поскольку вы встраиваете этот текст в HTML, вам необходимо htmlescape:

AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&amp;sortmethod1=147')

Вот почему вы заканчиваете:

<a href="javascript:AJAX_Get('http://10.0.0.195/program.exe?Qry147=M%2526S&amp;sortmethod1=147')" title='Refresh'>Refresh</a>

Обычно я избегаю этих проблем с кодированием, не помещая строку M&S непосредственно в событие onclick или в привязку. В общем случае вы не можете кодировать событие onclick и привязку одним и тем же способом, поскольку процесс декодирования для обоих отличается:

onclick: html -> js -> url
anchor: html -> url -> js -> url

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

function myQuery(q) {
    var encodedQ = encodeURIComponent(q); // TODO: which character encoding is used here?
    var url = 'http://10.0.0.195/program.exe?Qry147=' + encodedQ + '&sortmethod1=147';
    var response = AJAX_Get(url);
    // TODO: handle errors
}

Теперь вы можете написать:

<a href="javascript:myQuery('M&amp;S')">anchor</a>
<a onclick="myQuery('M&amp;S')">event</a>

Этот трюк работает, потому что в якоре больше нет %.

1 голос
/ 02 июля 2010

Я рекомендую хранить параметр в его незашифрованном виде и затем кодировать во время его использования, будь то в событии onClick или в привязке.

0 голосов
/ 02 июля 2010

Мне дали взломать решение из другого места, но оно работает довольно хорошо.

Простая замена:

с:

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

РЕДАКТИРОВАТЬ: только что заметил мой ответ здесь и понял, что это решение вызвало больше проблем, чем решило. В конце концов я нашел время, чтобы изменить его на правильную работу (поэтому он использует правильный метод побега в нужное время.

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